状态转移方程:dp[j][l]=max(dp[j][l],dp[j-v[i]][l-1]+w[i];可以将忍耐度视为背包容量,经验视为价值,怪的种数是物品种数。
<pre name="code" class="cpp">#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define MAXN 500010
int dp[505][505],v[MAXN],w[MAXN];
int main()
{
int l,s,n,m,i,j,k,a,b;
while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF)
{
for(i=0;i<k;i++)
{
scanf("%d %d",&w[i],&v[i]);
}memset(dp,0,sizeof(dp));
for(i=0;i<k;i++)//种数
{
for(j=v[i];j<=m;j++)//忍耐度
{
for(l=1;l<=s;l++)//个数
{
dp[j][l]=max(dp[j][l],dp[j-v[i]][l-1]+w[i]);
}
}
}
int flag=0;
for(i=0;i<=m;i++)//找出满足经验的最小忍耐度
{
if(flag) break;
for(j=0;j<=s;j++)
{
if(dp[i][j]>=n)
{
j=i,flag=1;break;
}
}
}
if(!flag) printf("-1\n");
else printf("%d\n",m-j);
}
return 0;
}