题目链接
这道题的是以魔兽为背景而做的一道题,游戏采用的是回合制(话说魔兽什么时候是回合制了)。你有n个技能,100点血量和100点蓝量,使用技能会消耗蓝量,每回合你回复t点蓝量,最高为100,boss的伤害是固定的q点。boss也会有100点血量,看你们谁先干死谁(注意,你先输出,不一定每回都要使用技能,你可以普攻会对boss造成1点伤害),如果你赢了输出最少的回合数,否则输出”My god”。
思路:boss的伤害是固定的,则表示你被打死的回合数是固定的,就是说你在回合之内打死他就可以了,设dp[i][j],i表示回合数,j表示当前蓝量,dp[i][j]表示第i回合的,蓝量为j的时候对boss造成的最大伤害。把普通攻击也看作是一种伤害,则状态转移为dp[i][temp] = max(dp[i][temp],dp[i][j] + skill[k].second);temp = min(100,j-skill[k].first+t)。
状态转移有不懂的就看代码吧。
我也是看了一些代码才懂的。
我看的博客
代码如下:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <cstring>
#define N 105
#define INF 1e9+7
using namespace std;
typedef pair<int,int> PII;
PII skill[N]; //技能数组,first表示蓝耗,second表示伤害。
int dp[N][N];//第i个回合时
int n,t,q;
int main(){
while(cin >> n >> t >> q && n && t && q){
for (int i = 1;i <= n;i++){
cin >> skill[i].first >> skill[i].second;
}
skill[0].first = 0; //把普攻也看作是一种技能,这点对下面dp的状态转移很重要
skill[0].second = 1;
int rou = 100/q; //回合数
if (100%q) rou++;
for (int i = 0;i < N;i++){
fill(dp[i],dp[i]+ N,-INF);
}
dp[0][100] = 0;
try{//try我也是新学的,是c++里面的东西,有不懂的可以去看一下c++里面的讲解。
for(int i = 1;i<= rou ;i++)
for(int j = 0;j <= 100;j++)
for (int k = 0;k <= n;k++)
if (j >= skill[k].first){
int temp = min(100,j-skill[k].first+t);
//状态转移我理解了好久,如果不懂的话可以多琢磨一下。
dp[i][temp] = max(dp[i][temp],dp[i-1][j]+skill[k].second);
if (dp[i][temp] >= 100) throw i;
}
cout << "My god" << endl;
}
catch(int ans){
cout << ans << endl;
}
}
return 0;
}