和普通的完全背包不同的地方时多了物品选取的限制,因此需要增加一维
dp[i][j][k]表示前i种物品,选取j个放入容量为k的背包中所能得到的最大价值
这里和一维的背包一样可以利用滚动数组省略一维即
dp[i][j] 表示前选取i个放入容量为j的背包所能得到的最大价值
dp[i,j] = max(dp[i,j],dp[i-1][j-w[k]]+v[k]);
1 #include <cstdio> 2 #include <cstring> 3 #include <string> 4 #include <algorithm> 5 #include <iostream> 6 using namespace std; 7 #define INF 0x3fffffff 8 const int maxn = 105; 9 const int maxv = 105; 10 int dp[maxv][maxn],w[maxn],v[maxn]; 11 int main() 12 { 13 //freopen("in.txt","r",stdin); 14 int n,m,k,s; 15 while(cin>>n>>m>>k>>s) 16 { 17 for(int i = 1;i<=k;++i) 18 scanf("%d%d",v+i,w+i); 19 memset(dp,0,sizeof(dp)); 20 int flag = 0,ans = -1; 21 for(int j = 0;j<=m;++j) 22 { 23 for(int i = 1;i<=s;++i) 24 { 25 for(int x = 1;x<=k;++x) 26 if(j>=w[x]){ 27 dp[i][j] = max(dp[i][j],dp[i-1][j-w[x]]+v[x]); 28 if(dp[i][j]>=n){flag = 1;ans = j;break;} 29 } 30 if(flag)break; 31 } 32 if(flag)break; 33 } 34 if(flag)printf("%d\n",m-ans); 35 else puts("-1"); 36 } 37 return 0; 38 }
时间: 2024-10-09 22:13:33