HDU 3008 Warcraft,动态规划,滚动数组
2015-08-31 20:36
288 查看
题目地址
之所以总结这道题是因为,这个算是自己想出来的吧,虽然简单但是也是费了不少功夫,的确在确立dp的含义时总是感觉无从下手,不过后来静下来想想居然出来了。
题意:(完全被我改编)回合制游戏,总量固定的HP,SP,普攻与多种技能每次(秒)选一种,BOSS只有普攻,而你有多个技能可选,但耗费SP不同,每秒末SP有少量恢复。每回合以秒为单位,你出招在BOSS前,问最少多少秒胜利。
感受:思考DP时,dp代表什么,可能需要尝试【先确定一个不行了再换,不要不思考】。其实一开始自己没想对但是已确立 dp[x][y]=z,x,y,z分别要代表 剩余SP,BOSS剩余HP,时间t,后来感觉x应该代表t,于是思路才出来。 不知这种题也不知算不算dp,毕竟就相当于罗列出每个时刻所有可能的情况,不过也的确用了已经获得信息。
trick: 滚动数组,还有就是把普攻也算作技能加入技能列表,方便计算。
之所以总结这道题是因为,这个算是自己想出来的吧,虽然简单但是也是费了不少功夫,的确在确立dp的含义时总是感觉无从下手,不过后来静下来想想居然出来了。
题意:(完全被我改编)回合制游戏,总量固定的HP,SP,普攻与多种技能每次(秒)选一种,BOSS只有普攻,而你有多个技能可选,但耗费SP不同,每秒末SP有少量恢复。每回合以秒为单位,你出招在BOSS前,问最少多少秒胜利。
感受:思考DP时,dp代表什么,可能需要尝试【先确定一个不行了再换,不要不思考】。其实一开始自己没想对但是已确立 dp[x][y]=z,x,y,z分别要代表 剩余SP,BOSS剩余HP,时间t,后来感觉x应该代表t,于是思路才出来。 不知这种题也不知算不算dp,毕竟就相当于罗列出每个时刻所有可能的情况,不过也的确用了已经获得信息。
trick: 滚动数组,还有就是把普攻也算作技能加入技能列表,方便计算。
#include<string.h> #include<stdio.h> #define MAXNUM 102 int main(){ int n,t,q; int i,j,k; char cost[MAXNUM],power[MAXNUM]; char dp[2][MAXNUM]; int maxt; int tmp_hp,tmp_sp; bool f; while(1){ scanf("%d %d %d",&n,&t,&q); if( n==0 && n==t && n==q )break; for(j=0;j<n;j++){ scanf("%d %d",&cost[j],&power[j]); } cost =0; power =1; //为了方便处理,合并普攻 maxt=99/q+1; //最大时间要求 memset(dp[0],-1,sizeof(dp[0])); dp[0][100]=100; f=false; for(i=1;i<=maxt;i++){ memset(dp[i&1],-1,sizeof(dp[i&1])); //滚动数组 for(k=1;k<=100;k++){ if( dp[ (i+1)&1 ][k] != -1 ){ //两个循环不要反,这里压缩很大 for(j=0;j<=n;j++){ if( k >= cost[j] ){ tmp_hp=dp[ (i+1)&1 ][k]-power[j]; if(tmp_hp<=0){ f=true; break; } //成功 tmp_sp=k-cost[j]+t; //加上每秒补入的能量 if(tmp_sp>100)tmp_sp=100; if(dp[i&1][tmp_sp]==-1 || dp[i&1][tmp_sp]>tmp_hp){ dp[i&1][tmp_sp]=tmp_hp; //选取最小的加入 } } } if(f)break; } } if(f)break; } i>maxt?printf("My god\n"):printf("%d\n",i); } return 0; }
相关文章推荐