hdu3008 Warcraft 【动态规划】【背包问题】

解题思路:

我们可以先算出被boss打死的时间m;
设f[i][j]为第i秒后剩余法力值j时对boss的伤害。
由于每秒法力值有回复且有上届,所以用i-1转移到i的方式比较难写,改用i转移到i+1。
转移方程为:f[i+1][x]=max(f[i][j]+c[k]),x=min(j-w[k]+t,100)。
可以将无法到达的状态跳过节省时间,不跳过也对,因为其不优。
一旦f[i][j]>=100 就可以输出i,然后break了。
如果一直没输出,就说明会挂,输出“My god”;

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#define ll long long
using namespace std;

int getint() 
{
    int i=0,f=1;char c;
    for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());
    if(c=='-')c=getchar(),f=-1;
    for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
    return i*f;
}

const int N=105;
int n,m,t,q;
int w[N],c[N],f[N][N];

int main()
{
    //freopen("lx.in","r",stdin);
    while(n=getint())
    {
        t=getint(),q=getint();
        if(!n&&!t&&!q)break;
        memset(f,-1,sizeof(f));
        m=(100%q)?100/q+1:100/q;
        for(int i=1;i<=n;i++)
            w[i]=getint(),c[i]=getint();
        int bz=0;
        f[0][100]=0;
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<=100;j++)
            {
                if(f[i][j]==-1)continue;
                int x=min(j+t,100);
                f[i+1][x]=max(f[i+1][x],f[i][j]+1);
                if(f[i+1][x]>=100)
                {
                    bz=1;
                    cout<<i+1<<'\n';
                    break;
                }
                for(int k=1;k<=n;k++)
                {
                    if(j<w[k])continue;
                    x=min(j-w[k]+t,100);
                    f[i+1][x]=max(f[i+1][x],f[i][j]+c[k]);
                    if(f[i+1][x]>=100)
                    {
                        bz=1;
                        cout<<i+1<<'\n';
                        break;
                    }
                }
                if(bz)break;
            }
            if(bz)break;
        } 
        if(!bz)puts("My god");
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值