题目思路:完全背包,dp[i][j]代表,砍j只怪,用i点疲劳最多能获得的经验值.
和平常的完全背包不一样的是多了一个限制条件:最多只砍S只怪,所以我们应该多一重循环来q:for 1->S,代表某种怪砍q只。
代码:
#include<cstdio> #include<stdio.h> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #include<string> #include<cstring> #include<vector> #include<queue> #define INF 0x3f3f3f3f #define MAX 1005 using namespace std; int dp[MAX][MAX],w[MAX],v[MAX]; int main() { int n,m,k,s,i,j,q,minn; while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF) { minn=INF; memset(dp,0,sizeof(dp)); for(i=1;i<=k;i++) { scanf("%d%d",&v[i],&w[i]); } for(i=1;i<=m;i++) { for(j=1;j<=k;j++) { for(q=1;q<=s;q++) { int cnt=1; while(cnt*w[j]<=i && cnt<=q) { dp[i][q]=max(dp[i][q],dp[i-cnt*w[j]][q-cnt]+cnt*v[j]); cnt++; } } } if(dp[i][s]>=n)//如果获得的经验已经大于n就没必要进行下去了 break; } if(i<=m) printf("%d ",m-i); else printf("-1 "); } return 0; }