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 }
把每一件简单的事情做好,就是不简单;把每一件平凡的事情做好,就是不平凡!相信自己,创造奇迹~~