HDU 3008 Warcraft(DP之状态的保存)
2016-07-13 19:53
330 查看
Problem Description
Have you ever played the Warcraft?It doesn't matter whether you have played it !We will give you such an experience.There are so many Heroes in it,but you could only choose one of them.Each Hero has his own skills.When such a Skill is used ,it costs some MagicValue,but
hurts the Boss at the same time.Using the skills needs intellegence,one should hurt the enemy to the most when using certain MagicValue.
Now we send you to complete such a duty to kill the Boss(So cool~~).To simplify the problem:you can assume the LifeValue of the monster is 100, your LifeValue is 100,but you have also a 100 MagicValue!You can choose to use the ordinary Attack(which doesn't
cost MagicValue),or a certain skill(in condition that you own this skill and the MagicValue you have at that time is no less than the skill costs),there is no free lunch so that you should pay certain MagicValue after you use one skill!But we are good enough
to offer you a "ResumingCirclet"(with which you can resume the MagicValue each seconds),But you can't own more than 100 MagicValue and resuming MagicValue is always after you attack.The Boss is cruel , be careful!
Input
There are several test cases,intergers n ,t and q (0<n<=100,1<=t<=5,q>0) in the first line which mean you own n kinds of skills ,and the "ResumingCirclet" helps you resume t points of MagicValue per second and q is of course the hurt points of LifeValue the
Boss attack you each time(we assume when fighting in a second the attack you show is before the Boss).Then n lines follow,each has 2 intergers ai and bi(0<ai,bi<=100).which means using i skill costs you ai MagicValue and costs the Boss bi LifeValue.The last
case is n=t=q=0.
Output
Output an interger min (the minimun time you need to kill the Boss)in one line .But if you die(the LifeValue is no more than 0) ,output "My god"!
Sample Input
4 2 25
10 5
20 10
30 28
76 70
4 2 25
10 5
20 10
30 28
77 70
0 0 0
Sample Output
4
My god
Hint
Hint:
When fighting,you can only choose one kind of skill or just to use the ordinary attack in the whole second,the ordinary attack costs the Boss 1
points of LifeValue,the Boss can only use ordinary attack which costs a whole second at a time.Good Luck To You!
Source
2009 Multi-University Training
Contest 11 - Host by HRBEU
题意:
英雄和boss的生命都是100,boss打英雄的伤害固定,英雄打boss可以选择普通攻击或者使用技能
使用普通攻击造成伤害为1,不花费魔法
使用技能则可以每次从n中技能种选一种攻击,造成伤害bi,花费魔法ai
英雄初始魔法100,每秒恢复魔法t,但是恢复也不会使魔法超过100
问打死boss的最短时间,不能打死输出My god
分析:
第一眼准备对技能贪心,不过很快否定了,还是回到DP的正轨。。。
此题不难,但是让我对于状态的保存加深了理解
一般DP的状态保存我是看题目求什么,比如这题求最短时间,状态有魔法和boss血量
(英雄血量不用管,boss伤害固定表示英雄到时间了自然会死)
本来我想用dp[i][j]表示剩余i魔法,打掉boss j血的状态花费的最少时间
然后初始状态是dp[100][0] = 0,求解的答案是dp[k][100](k从0到100)里面的最小值
这个想法很正常,我以前做DP都是这么想的,但是这题有点麻烦。。。
因为英雄的魔法每秒会有恢复,如果用dp记录的是时间,怎么体现魔法的恢复?
于是换了一种记录状态的方法,既然魔法随时间恢复,那么显然要把时间这个状态放在数组下标里
所以我用dp[i][j]表示在i时间内,剩余j魔法的状态下打掉boss最大的血量
那么只要找到最小的i里面存在dp>=100就好
状态转移:
dp[i][min(j-a[k]+t,100)] = max(dp[i][min(j-a[k]+t,100)],dp[i-1][j] + b[k]);
其中注意:1.剩余魔法不会超过100
2. dp[i][min(j-a[k]+t,100)]状态由dp[i-1][j]状态转移而来的条件是 dp [i-1][j]状态存在(不为-1)
具体见代码:
Have you ever played the Warcraft?It doesn't matter whether you have played it !We will give you such an experience.There are so many Heroes in it,but you could only choose one of them.Each Hero has his own skills.When such a Skill is used ,it costs some MagicValue,but
hurts the Boss at the same time.Using the skills needs intellegence,one should hurt the enemy to the most when using certain MagicValue.
Now we send you to complete such a duty to kill the Boss(So cool~~).To simplify the problem:you can assume the LifeValue of the monster is 100, your LifeValue is 100,but you have also a 100 MagicValue!You can choose to use the ordinary Attack(which doesn't
cost MagicValue),or a certain skill(in condition that you own this skill and the MagicValue you have at that time is no less than the skill costs),there is no free lunch so that you should pay certain MagicValue after you use one skill!But we are good enough
to offer you a "ResumingCirclet"(with which you can resume the MagicValue each seconds),But you can't own more than 100 MagicValue and resuming MagicValue is always after you attack.The Boss is cruel , be careful!
Input
There are several test cases,intergers n ,t and q (0<n<=100,1<=t<=5,q>0) in the first line which mean you own n kinds of skills ,and the "ResumingCirclet" helps you resume t points of MagicValue per second and q is of course the hurt points of LifeValue the
Boss attack you each time(we assume when fighting in a second the attack you show is before the Boss).Then n lines follow,each has 2 intergers ai and bi(0<ai,bi<=100).which means using i skill costs you ai MagicValue and costs the Boss bi LifeValue.The last
case is n=t=q=0.
Output
Output an interger min (the minimun time you need to kill the Boss)in one line .But if you die(the LifeValue is no more than 0) ,output "My god"!
Sample Input
4 2 25
10 5
20 10
30 28
76 70
4 2 25
10 5
20 10
30 28
77 70
0 0 0
Sample Output
4
My god
Hint
Hint:
When fighting,you can only choose one kind of skill or just to use the ordinary attack in the whole second,the ordinary attack costs the Boss 1
points of LifeValue,the Boss can only use ordinary attack which costs a whole second at a time.Good Luck To You!
Source
2009 Multi-University Training
Contest 11 - Host by HRBEU
题意:
英雄和boss的生命都是100,boss打英雄的伤害固定,英雄打boss可以选择普通攻击或者使用技能
使用普通攻击造成伤害为1,不花费魔法
使用技能则可以每次从n中技能种选一种攻击,造成伤害bi,花费魔法ai
英雄初始魔法100,每秒恢复魔法t,但是恢复也不会使魔法超过100
问打死boss的最短时间,不能打死输出My god
分析:
第一眼准备对技能贪心,不过很快否定了,还是回到DP的正轨。。。
此题不难,但是让我对于状态的保存加深了理解
一般DP的状态保存我是看题目求什么,比如这题求最短时间,状态有魔法和boss血量
(英雄血量不用管,boss伤害固定表示英雄到时间了自然会死)
本来我想用dp[i][j]表示剩余i魔法,打掉boss j血的状态花费的最少时间
然后初始状态是dp[100][0] = 0,求解的答案是dp[k][100](k从0到100)里面的最小值
这个想法很正常,我以前做DP都是这么想的,但是这题有点麻烦。。。
因为英雄的魔法每秒会有恢复,如果用dp记录的是时间,怎么体现魔法的恢复?
于是换了一种记录状态的方法,既然魔法随时间恢复,那么显然要把时间这个状态放在数组下标里
所以我用dp[i][j]表示在i时间内,剩余j魔法的状态下打掉boss最大的血量
那么只要找到最小的i里面存在dp>=100就好
状态转移:
dp[i][min(j-a[k]+t,100)] = max(dp[i][min(j-a[k]+t,100)],dp[i-1][j] + b[k]);
其中注意:1.剩余魔法不会超过100
2. dp[i][min(j-a[k]+t,100)]状态由dp[i-1][j]状态转移而来的条件是 dp [i-1][j]状态存在(不为-1)
具体见代码:
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<set> #include<stack> #include<cmath> #include<map> #include<stdlib.h> #include<cctype> #define mem(a,x) memset(a,x,sizeof(a)) #define esp 1e-8 using namespace std; typedef long long ll; const int N = 100; int a[N+5],b[N+5]; int dp[N+5][N+5]; int main() { int n,t,q; while (scanf("%d %d %d",&n,&t,&q) == 3&&(n||t||q)) { for (int i = 1;i <= n;++i) scanf("%d %d",a+i,b+i); a[0] = 0,b[0] = 1;//普通攻击 mem(dp,-1);int dt = 100/q; if (100%q) ++dt; for (int i = 0;i <= n;++i) { if (a[i]<=100)//技能花费 { dp[1][100-a[i]] = b[i]; } } for (int i = 2;i <= dt;++i) { for (int j = 0;j <= 100;++j) { for (int k = 0;k <= n;++k) { if (dp[i-1][j] == -1) continue;//转移的前状态必须是存在的才能转移 if (min(100,j+t) >= a[k])//该技能可以使用 { //那么进行决策 dp[i][min(j-a[k]+t,100)] = max(dp[i][min(j-a[k]+t,100)],dp[i-1][j] + b[k]); } } } } bool fd = 0; for (int i = 1;i <= dt;++i)//找最小时间 { for (int j = 0;j <= 100;++j) { if (dp[i][j] >= 100) { fd = 1; printf("%d\n",i); break; } } if (fd) break; } if (!fd) puts("My god"); } return 0; }
相关文章推荐
- 详解Android应用中屏幕尺寸的获取及dp和px值的转换
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- LFC1.0.0 版本发布
- Android dpi,dip,dp的概念以及屏幕适配
- Android px、dp、sp之间相互转换
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法
- Android根据分辨率进行单位转换-(dp,sp转像素px)
- android 尺寸 dp,sp,px,dip,pt详解
- 高精度加法——杭电1002
- DP问题各种模型的状态转移方程
- POJ-1695-Magazine Delivery-dp
- nyoj-1216-整理图书-dp
- TYVJ1193 括号序列解题报告
- 对DP的一点感想
- TYVJ上一些DP的解题报告
- Hdu2066(一个人的旅行)