HDU 3008.Warcraft

320

题目



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

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  



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!


题解


magic[i] hurt[i] 表示第 i 个技能的耗蓝和伤害( magic[0] = 0 hurt[0] = 1 代表普通攻击)
dp[i][j] 表示第 i 秒后,剩下 j 点法力值能造成的最高伤害

很容易写出状态转移方程
dp[i][j - magic[k]] = max{ dp[i-1][j] + hurt[k] }

由于每次只用到上一秒的数据,并且计算顺序比较混乱,可以采用滚动数组的方法(虽然直接写也不可能爆内存)

最后就是要注意 Boss 打你是否是正好打死,需要判断是否除尽

代码


/*
By:OhYee
Github:OhYee
Blog:http://www.oyohyee.com/
Email:oyohyee@oyohyee.com

かしこいかわいい?
エリーチカ!
要写出来Хорошо的代码哦~
*/
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <functional>
#include <bitset>
using namespace std;

const int maxn = 105;

int dp[2][maxn];
int magic[maxn];
int hurt[maxn];

bool Do() {
    int n,t,q;
    scanf("%d%d%d",&n,&t,&q);

    if(n == 0 && t == 0 && q == 0)
        return false;

    memset(dp,0,sizeof(dp));

    for(int i = 1;i <= n;i++)
        scanf("%d%d",&magic[i],&hurt[i]);

    magic[0] = 0;
    hurt[0] = 1;

    int time = (100 % q == 0) ? 100 / q : 100 / q + 1;

    for(int i = 1;i <= time;i++) {
        int *thisdp = dp[i & 1];
        int *lastdp = dp[!(i & 1)];

        for(int j = 100;j >= 0;j--) {
            thisdp[j] = 0;
            if(j == 100)
                for(int k = 1;k <= t;k++)
                    lastdp[100] = max(lastdp[100],lastdp[100 - k]);
            else
                if(j - t >= 0)
                    lastdp[j] = lastdp[j - t];
                else
                    lastdp[j] = 0;
        }
        for(int j = 100;j >= t;j--)
            for(int k = 0;k <= n;k++)
                if(j - magic[k] >= 0) {
                    thisdp[j - magic[k]] = max(
                        thisdp[j - magic[k]],
                        lastdp[j] + hurt[k]
                    );
                    if(thisdp[j - magic[k]] >= 100) {
                        printf("%d\n",i);
                        return true;
                    }
                }
    }

    printf("My god\n");
    return true;
}

int main() {
    while(Do());
    return 0;
}
发布评论
  • 点击查看/关闭被识别为广告的评论