解题思路:题目看起来很雷人,实际上就是普通的TSP,只是每次状态转移略显麻烦些。为什么可以转换为TSP呢?因为每只怪兽都只要打一次,而且打完若干只怪兽后剩下的经验值、攻击力、防御力都是一样的,只有hp会随顺序改变,那么用一个数组dp[i]表示i状态时的最多hp,每次更新都去计算i状态下的各项属性。我把hp,at,def,ex都封装进一个结构体,意思是一样的,状态转移见代码。
测试数据:
100 80 100 5 5 5
2
ZhangFei 95 75 100 100
XuChu 90 90 100 90
100 75 100 5 5 5
1
GuanYu 95 85 100 100
C艹代码:
#include <stdio.h> #include <string.h> #define MIN 21 #define MAX 1<<21 #define max(a,b) (a)>(b)?(a):(b) struct node { int at,def,hp,ex; }dp[MAX],enemy[MIN],add; int n,m,state,ans; void State_Dp() { int i,j,k,meat,heat,mtime,htime; int curhp,curex,curat,curdef; for (i = 0; i < (1<<n); ++i) for (j = 0; j < n; ++j) if (!(i & (1<<j)) && dp[i].hp) { meat = max(1,dp[i].at - enemy[j].def); //我们打对方多少hp heat = max(1,enemy[j].at - dp[i].def); //对方打我们多少hp mtime = (dp[i].hp + heat - 1) / heat; //我们能撑住几次攻击 htime = (enemy[j].hp + meat - 1) / meat; //对方能撑住几次攻击 if (mtime < htime) continue; //我们先倒下 curhp = dp[i].hp - (htime - 1) * heat; //攻击完的状态 curex = dp[i].ex + enemy[j].ex; curat = dp[i].at,curdef = dp[i].def; if (curex >= 100) { //升级 curex -= 100; curhp += add.hp; curat += add.at; curdef += add.def; } if (curhp >= dp[i|(1<<j)].hp) { //更新答案 dp[i|(1<<j)].hp = curhp; dp[i|(1<<j)].ex = curex; dp[i|(1<<j)].at = curat; dp[i|(1<<j)].def = curdef; } } } int main() { int i,j,k; char tp[30]; while (scanf("%d%d%d",&dp[0].at,&dp[0].def,&dp[0].hp) != EOF) { dp[0].ex = 0; scanf("%d%d%d",&add.at,&add.def,&add.hp); scanf("%d",&n); for (i = 0; i < n; ++i) scanf("%s %d%d%d%d",tp,&enemy[i].at,&enemy[i].def,&enemy[i].hp,&enemy[i].ex); for (i = 1; i < (1<<n); ++i) dp[i].hp = 0; State_Dp(); if (dp[(1<<n)-1].hp) printf("%d\n",dp[(1<<n)-1].hp); else printf("Poor LvBu,his period was gone.\n"); } }
本文ZeroClock原创,但可以转载,因为我们是兄弟。