题意:吕布大战群雄,每位英雄都有自己的攻击力,防御力,还有hp(血量),吕布比较特殊,当他积累够100的经验值时他可以升级 。。升级的话加属性。
这个比较公平一点,是单挑,每一位英雄轮流与吕布作战,当吕布杀死一个英雄后,可以得到一定的经验值,问吕布能不能杀死所有的英雄,如果可以的话,求出
最后能剩余的最大血量。
分析:这题目怎么被分到搜索专题了?哎,怎么剪枝还是超时……
确实是比较裸的状态压缩DP,自底向上实现状态转移
#include<iostream> #include<algorithm> using namespace std; struct hero { int att,def,hp,lev; int exp; }dp[(1<<20)+1]; struct enemy { int att,def,hp,exp; }; enemy e[25]; int att,def,hp; void init() { for(int i=1;i<(1<<20)+1;i++) dp[i].hp=0; } int main() { char str[25]; while(scanf("%d %d %d %d %d %d",&dp[0].att,&dp[0].def,&dp[0].hp,&att,&def,&hp)==6) { int n=0; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%s %d %d %d %d",str,&e[i].att,&e[i].def,&e[i].hp,&e[i].exp); init(); dp[0].lev=1; dp[0].exp=0; for(int j=0;j<(1<<n)-1;j++) { if(dp[j].hp<=0) continue; for(int k=0;k<n;k++) { hero temp=dp[j]; if((j&(1<<k))!=0) continue; int sub=max(temp.att-e[k].def,1); int sub1=max(e[k].att-temp.def,1); int time=(e[k].hp/sub)+((e[k].hp%sub==0)?-1:0); temp.hp-=time*sub1; if(temp.hp<=0) continue; temp.exp+=e[k].exp; if(temp.exp>=temp.lev*100) { temp.lev++; temp.att+=att; temp.def+=def; temp.hp+=hp; } if(temp.hp>dp[j|(1<<k)].hp) dp[j|(1<<k)]=temp; } } if(dp[(1<<n)-1].hp<=0) { puts("Poor LvBu,his period was gone."); continue; } printf("%d\n",dp[(1<<n)-1].hp); } return 0; }