题意:有点繁琐,这里不叙述了;
思路:题目变量有点多,但是有些是不变的,所以定义状态的时候可以把这些忽略掉,然后很明显可以定义状态了,定义完状态之后发现其实是一个01背包,然后照着01背包的思路写就对了;
定义状态dp[magic_value][attack_times],右边下标对应攻击完第k次后,左边下标对应的值为剩下的魔法值,数组的值为boss剩下的血量。
状态转移方程
dp[magic_value][k] = max(dp[magic_value][k] , dp[j][k - 1] + skill[i].dps);
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110;
const int MAGIC_VALUE = 110;
const int ATTACK_TIMES = 110;
int dp[MAGIC_VALUE][ATTACK_TIMES];
struct node{
int cost, dps;
}skill[N];
int main(){
int n, t, q;
while (scanf("%d%d%d", &n, &t, &q)){
if (n == 0&&t == 0&&q == 0)
break;
memset(dp, 0, sizeof(dp));
int i, j, k, res = 0;
for (i = 0;i < n;i++)
scanf("%d%d", &skill[i].cost, &skill[i].dps);
skill[n].cost = 0, skill[n].dps = 1;
for (k = 1;k <= 100;k++){ //最多攻击100次
if (res)
break;
for (i = 0;i <= n;i++)
for (j = 100;j >= skill[i].cost;j--){
int mag = j - skill[i].cost + t;
if (mag > 100)
mag = 100;
dp[mag][k] = max(dp[mag][k] , dp[j][k - 1] + skill[i].dps);
if (dp[mag][k] >= 100)
res = k;
}
}
if ((res - 1) * q >= 100)
printf("My god\n");
else
printf("%d\n", res);
}
return 0;
}