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

来源:互联网 发布:找数据的网站 编辑:程序博客网 时间:2024/06/04 23:25

解题思路:

我们可以先算出被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 longusing 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;}
原创粉丝点击