HDU 3008 Warcraft(DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3008

题目大意:人有100血和100魔法,每秒增加 t 魔法(不能超过100)。n个技能,每个技能消耗cost[i]魔法值,造成hurt[i]伤害。普通攻击不消耗魔法,每秒1伤害。

boss有100血,每秒对人造成q伤害。每秒内,人先攻击,boss后攻击。问最少多少秒杀死boss?

Sample Input

4 2 25
10 5
20 10
30 28
76 70
4 2 25
10 5
20 10 3
0 28
77 70
0 0 0

Sample Output

4

My god

分析:普通攻击可以看做是魔法消耗为0,伤害为1的魔法攻击(这一小点能够节省时间)

  dp[i][j]表示第 i 秒 有 j 的魔法值时,boss受到伤害的值。

  if(   dp[ i ][ 上次剩余魔法 + 补充魔法 - K技能消耗 ]      <    dp[ i-1 ][ 上次剩余魔法 ] +  K技能打掉血量  )

            dp[ i ][ 上次剩余魔法 + 补充魔法 - K技能消耗 ]      =    dp[ i-1 ][ 上次剩余魔法 ] +  K技能打掉血量 ;

很简单的状态转移吧,只是我不明白,比如如果第一秒只用普通攻击,那即使不消耗魔法,为什么dp[1][1...99]也要计算?

代码如下:

 1 # include<stdio.h>
 2 # include<string.h>
 3 
 4 int cost[101],hurt[101]; //魔法 和 伤害
 5 int dp[101][101]; //
 6 
 7 int main(){
 8     int n,t,q;
 9     int i,j,k,temp,flag;
10     cost[0] = 0;    hurt[0] = 1;    //普通攻击
11 
12     while(scanf("%d%d%d",&n,&t,&q) && n && t && q)
13     {
14         for(i=1;i<=n;i++)
15             scanf("%d%d",&cost[i],&hurt[i]);
16         memset(dp,0,sizeof(dp));
17         flag = 0;
18         for(i=1;(i-1)*q<100;i++)    //不能是<=100,因为自己死了的话,算输
19         {
20             for(j=0;j<=100;j++)
21             {
22                 for(k=0;k<=n;k++)
23                 {
24                     if(j-cost[k] < 0)
25                         continue;
26                     temp = (j-cost[k]+t>100) ? 100 : j-cost[k]+t;    //回复魔法超过100,按100计算
27                     if(dp[i][temp] < dp[i-1][j] + hurt[k])
28                         dp[i][temp] = dp[i-1][j] + hurt[k];
29                     if(dp[i][temp] >= 100) //一旦boss伤害超过100,结束
30                     {    flag=1; break;  }         
31                 }
32                 if(flag) break;
33             }
34             if(flag) break;
35         }
36         if(flag) printf("%d\n",i);
37         else  printf("My god\n");
38     }
39     return 0;
40 }

 

你可能感兴趣的:(HDU)