题目描述:
解析:
这道题是很明显的完全背包问题,所不同的是在背包容量限制的基础上限定了最多可以拿取的物品数量。最开始做的时候不知道新增的限制条件怎么使用,参考了网上的代码,写一下思路:
既然新增了一条限制,也就是要保证拿取的数量要小于限制的数量,那么可以对原有的数组新增加一个维度:
状态设计:dp[z][j]表示杀z个怪且花费不超过j的情况下得到的最大经验值
状态转移方程:dp[z][j]=max(dp[z][j],dp[z-1][j-b[i]]+a[i])
代码:
#include<stdio.h>
#include<string.h>
#define MAX 1000
int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int i,j,z,min;
int n,m,s,k,a[MAX],b[MAX],dp[102][MAX];
while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(dp,0,sizeof(dp));
min=65535;
for(i=1;i<=k;i++)
scanf("%d%d",&a[i],&b[i]);
for(i=1;i<=k;i++)
{
for(j=b[i];j<=m;j++)
{
for(z=1;z<=s;z++)
{
dp[z][j]=max(dp[z][j],dp[z-1][j-b[i]]+a[i]);
if(dp[z][j]>=n&&j<min)
min=j;
}
}
}
if(min==65535)
printf("-1\n");
else
printf("%d\n",m-min);
}
return 0;
}