hdu4415 不错的想法题
題意:
? ? ? ? ? 一個人他有一定的血,有一些怪物,他去殺怪物,有的怪物殺死他后還可以在不費自己血的情況下任意殺死一些怪物,問你他最多殺死多少怪物,在最多殺怪前提下最好用多少血,(大體題意是這樣).
思路:
? ? ? ?首先我們把怪物分成兩個集合,A一個是殺死他后可以免費殺死其他人的,B另一個是殺死他后不能免費殺死其他人的,分析下我們會發現,A集合我們只要殺死其中一個人就可以免費殺死其他人(肯定殺費血最少的),而且很有可能會攢下一些殺死B集合的機會.
其實無非兩種情況,殺A集合的和不殺A集合的,如果殺選擇殺A集合的那么我們肯定全殺掉,而花費的血就是A集合中血最少的那個,然后我們再把出了剛剛殺的那個以外,和B集合的所有放在一起排序稱為C,殺完A集合后會剩下一下免費殺人的機會,我們用這些機會去殺C中的人,既然是免費的肯定從最大的開始殺,殺完后如果沒殺沒的話我們就用自己的血從小的開始在接著殺,一直殺到自己血沒活著敵人沒了未知,這是第一種情況,第二種情況是不殺A集合的,只殺B集合的,這種好辦,直接把B排序一便,從小的開始能殺多少殺多少,最后在兩種方案中選擇一個最優的輸出來就行了...
/*
1 只殺bi為0的 ,排序下,直接殺就行了;
2 殺bi不為0的 ,先殺死最小的那個bi不為0的,然后得到 s = b1 + b2 + b3 +++
然后在殺死其余的 n1 + n2 - 1 - s 的怪,就ok了;?
*/
#include<stdio.h>?
#include<algorithm>
#define N 100000 + 100
using namespace std;
typedef struct
{
? ?int xp ,hp;
}NODE;
NODE node1[N] ,node2[N];
bool camp(NODE a ,NODE b)
{
? ?return a.hp < b.hp;
}
int main ()
{
? ?int t ,i ,n ,v ,n1 ,n2;
? ?int ans1_n ,ans2_n ,ans1_hp ,ans2_hp;
? ?int cas = 1 ,s;
? ?scanf("%d" ,&t);
? ?while(t--)
? ?{
? ? ? scanf("%d %d" ,&n ,&v);
? ? ? n1 = n2 = s = 0;?
? ? ? NODE temp;
? ? ? for(i = 1 ;i <= n ;i ++)
? ? ? {
? ? ? ? ?scanf("%d %d" ,&temp.hp ,&temp.xp);
? ? ? ? ?if(temp.xp)
? ? ? ? ?{
? ? ? ? ? ? node2[++n2] = temp;
? ? ? ? ? ? s += temp.xp;
? ? ? ? ?}
? ? ? ? ?else
? ? ? ? ?node1[++n1] = temp;
? ? ? }?
? ? ? ans1_n = ans1_hp = 0;
? ? ? sort(node1 + 1 ,node1 + n1 + 1 ,camp);
? ? ? int vv = v;
? ? ? for(i = 1 ;i <= n1 ;i ++)
? ? ? {
? ? ? ? ?if(vv < node1[i].hp) break;?
? ? ? ? ?ans1_n ++;
? ? ? ? ?ans1_hp += node1[i].hp;
? ? ? ? ?vv -= node1[i].hp;
? ? ? }
? ? ? ? ?
? ? ? sort(node2 + 1 ,node2 + n2 + 1 ,camp);
? ? ? ? ?
? ? ? if(v < node2[1].hp)
? ? ? {
? ? ? ? ?printf("Case %d: %d %d\n" ,cas ++ ,ans1_n ,ans1_hp);
? ? ? ? ?continue;
? ? ? }
? ? ? ? ?
? ? ? ans2_n = 1;
? ? ? ans2_hp = node2[1].hp;
? ? ? v -= node2[1].hp;
? ? ? ? ?
? ? ? if(s >= n1 + n2 - 1)
? ? ? {
? ? ? ? ?ans2_n = n1 + n2;
? ? ? ? ?if(ans1_n > ans2_n || ans1_n == ans2_n && ans1_hp < ans2_hp)
? ? ? ? ?printf("Case %d: %d %d\n" ,cas ++ ,ans1_n ,ans1_hp);
? ? ? ? ?else
? ? ? ? ?printf("Case %d: %d %d\n" ,cas ++ ,ans2_n ,ans2_hp);
? ? ? ? ?continue;
? ? ? }
? ? ? ??
? ? ? for(i = 2 ;i <= n2 ;i ++)
? ? ? node1[++n1] = node2[i];
? ? ? ? ?
? ? ? sort(node1 + 1 ,node1 + n1 + 1 ,camp);
? ? ? n1 -= s;
? ? ? vv = v; ??
? ? ? ans2_n += s;?
? ? ? for(i = 1 ;i <= n1 ;i ++)
? ? ? {
? ? ? ? ?if(vv < node1[i].hp) break;
? ? ? ? ?vv -= node1[i].hp;
? ? ? ? ?ans2_n ++;
? ? ? ? ?ans2_hp += node1[i].hp;
? ? ? }
? ? ? ? ?
? ? ? if(ans1_n > ans2_n || ans1_n == ans2_n && ans1_hp < ans2_hp)
? ? ? printf("Case %d: %d %d\n" ,cas ++ ,ans1_n ,ans1_hp);
? ? ? else
? ? ? printf("Case %d: %d %d\n" ,cas ++ ,ans2_n ,ans2_hp);
? ?}
? ?return 0;
}
? ?
總結
以上是生活随笔為你收集整理的hdu4415 不错的想法题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 二分于最大流之间的关系
- 下一篇: 交换两个数不引入第三个变量