題意:
乙個人他有一定的血,有一些怪物,他去殺怪物,有的怪物殺死他後還可以在不費自己血的情況下任意殺死一些怪物,問你他最多殺死多少怪物,在最多殺怪前提下最好用多少血,(大體題意是這樣).
思路:首先我們把怪物分成兩個集合,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
#include
#define n 100000 + 100
using namespace std;
typedef struct
node;
node node1[n] ,node2[n];
bool camp(node a ,node b)
int main ()
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 ++)
sort(node2 + 1 ,node2 + n2 + 1 ,camp);
if(v < node2[1].hp)
ans2_n = 1;
ans2_hp = node2[1].hp;
v -= node2[1].hp;
if(s >= n1 + n2 - 1)
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(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 不錯的想法題
題意 乙個人他有一定的血,有一些怪物,他去殺怪物,有的怪物殺死他後還可以在不費自己血的情況下任意殺死一些怪物,問你他最多殺死多少怪物,在最多殺怪前提下最好用多少血,大體題意是這樣 思路 首先我們把怪物分成兩個集合,a乙個是殺死他後可以免費殺死其他人的,b另乙個是殺死他後不能免費殺死其他人的,分析下我...
hdu4415 貪心好題
刺客殺人使用自己的刀需要消耗一定的耐久度,或者用殺人得到的刀,問用盡可能少的代價殺盡可能多的人 首先,如果殺了乙個有刀的人,最優解中有刀的人全部被殺完 證明 假設最優解中殺了x,不殺y,那麼殺了x後再殺y並不會使得自己的刀的數量有所減少,這種情況還多殺了乙個人,則這個不是最優解,矛盾了 將結果分為兩...
HDU1075 不錯的字典樹題
題意 給你多條英語對應火星文,然後在下面輸入一堆火星文,要你翻譯成英文,如果一些火星文沒有對應的英文的話就輸出原火星文就可以了,有就輸出英文。題解 一看到這道題就想到了map容器,奈何挺久沒用過了,導致我很難下手,還是去看了別人怎麼寫的記憶才慢慢復甦,怎麼說呢,stl是個神器,但是我用不習慣。orz...