HDU4415 Assassin’s Creed 2012ACM/ICPC 杭州赛区网络赛 F

HDU4415(枚举,贪心)

大意:

杀手有把耐久为m的“袖口刀”,一共有n个敌人,每个敌人都有防御值Ai ,杀死一个为Ai的敌人则m -= Ai,每个敌人有“能量刀”,杀死敌人后可以获取敌人的能量刀,能量值Bi是几就可以再杀几个人,刀可以叠加,Bi为0就是这个敌人没有能量刀。问消耗尽量小的m,最多可以杀多少敌人。

题解:

把敌人按照Bi分为a组和b组,a组的敌人都是没有能量刀的敌人(Bi=0),b组的Bi>0。

枚举1、只用袖口刀杀a组里的人,能杀多少是多少,杀完若m还有剩余,则尝试去杀b组的人,若能杀掉一个防御最低的,用得到的能量刀就能把b组的人全杀掉。

例如数据:

1
5
7 1
7 1
1 0
1 0
1 0

枚举2、仅用袖口刀去杀b组的人,不用能量刀,直到剩余的m值不够用了,在用能量刀接着杀,若能杀完,在用能量刀和袖口刀去杀a组的人

例如数据:

1
6 20
10 2
10 2
100 0
100 0
100 0
100 0

枚举3、用袖口刀杀掉b组防御最低的(杀不掉则回到枚举1),然后用得到的能量刀杀完b组的人,在用袖口刀和能量刀杀a组的人

例如数据:

1
5 5
10 1
4 1
5 2
100 0
1 0

然后比较3种枚举得到的值,得出答案,貌似贪心思想没大用到。。。

#include <iostream>
#include <vector>
#include <algorithm>
#define FOR(a,b) for(int i = (a);i &lt; (b);i ++) using namespace std; struct Enemy { int Ai,Bi; }; bool cmp(const Enemy&amp; a,const Enemy&amp; b) { return a.Ai &lt; b.Ai; } struct Ans { int num,cost; }; bool operator&lt;(const Ans&amp; a,const Ans&amp; b) { if(a.num == b.num) return a.cost &gt; b.cost; return a.num &lt; b.num; } vector&lt;Enemy&gt; b; vector&lt;int&gt; a; Ans afirst(int m) { Ans ans; ans.cost = 0,ans.num = 0; for(int i = 0; i &lt; a.size() &amp;&amp; m &gt;= a[i];i ++) { m -= a[i]; ans.num ++; ans.cost += a[i]; } if(!b.empty() &amp;&amp; m &gt;= b[0].Ai) ans.num += b.size(),ans.cost += b[0].Ai; return ans; } Ans bfirst(int m,int energy) { Ans ans; ans.num = 0,ans.cost = m; for(;ans.num &lt; b.size() &amp;&amp; m &gt;= b[ans.num].Ai;ans.num ++) m -= b[ans.num].Ai; ans.cost -= m; energy -= b.size() - ans.num; if(energy &gt;= a.size()) ans.num = a.size()+b.size(); else{ ans.num = b.size() + energy; for(int i = 0;i &lt;= a.size() - energy &amp;&amp; a[i] &lt;= m;i ++) ans.num ++,ans.cost += a[i],m -= a[i]; } return ans; } Ans banda(int m,int energy) { Ans ans; ans.num = 0,ans.cost = 0; ans.cost += b[0].Ai; m -= ans.cost; energy -= b.size() -1; if(energy &gt;= a.size()) ans.num = a.size() + b.size(); else { ans.num = b.size() + energy; for(int i = 0;i &lt;= a.size() - energy &amp;&amp; a[i] &lt;= m;i ++) ans.num ++,ans.cost += a[i],m -= a[i]; } return ans; } int main() { int n,m,num,cost,energy; Enemy enemy; Ans ans,ans1,ans2,ans3; int testcases; scanf(&quot;%d&quot;,&amp;testcases); for(int ca = 1; ca &lt;= testcases; ca ++) { a.clear(),b.clear(); num = 0,cost = 0; energy = 0; scanf(&quot;%d%d&quot;,&amp;n,&amp;m); FOR(0,n) { scanf(&quot;%d%d&quot;,&amp;enemy.Ai,&amp;enemy.Bi); if(enemy.Bi) b.push_back(enemy),energy += enemy.Bi; else a.push_back(enemy.Ai); } if(!b.empty()) sort(b.begin(),b.end(),cmp); if(!a.empty()) sort(a.begin(),a.end()); if(a.empty())//每个敌人都有剑 { if(m &gt;= b[0].Ai) printf(&quot;Case %d: %d %d\n&quot;,ca,b.size(),b[0].Ai); else printf(&quot;Case %d: 0 0\n&quot;,ca); continue; } //枚举1 只用自己的武器在a中杀人 ans1 = afirst(m); //枚举2 只用自己的武器杀b中的人 ans2 = bfirst(m,energy); //枚举3 杀一个b中的,用敌人的武器搞死完b,然后搞a ans3 = banda(m,energy); ans = ans1 &lt; ans2 ? ans2 : ans1; ans = ans &lt; ans3 ? ans3 : ans; printf(&quot;Case %d: %d %d\n&quot;,ca,ans.num,ans.cost); } }
本博客所有博文,若无专门说明皆为原创,转载请注明作者和出处!
原文地址:https://www.cnblogs.com/ifinver/p/2706477.html