解题思路:
我们可以先算出被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;
}