一开始看到这题就认为应该用dp做,先想到用二维,(表示处理到第i个物品时,前m个背包所能装的最大物品数)dp[m][i]=dp[m-1][i]+最后一个背包用来装第i个到n个物品所能获得的最大物品数,后面由于对0,1 背包不熟,加上这个dp方程思路都不怎么清晰,然后没写了。
后面自己又想用三维dp来做,写了个dp[i][m][v] 表示处理到第i个数时,前m个背包,最后一个容量为v时,所能装入的最大物品数。又因为最后一维只表示最后一个背包的状态,而前面一些背包的状态没考虑,所以又感觉不行。后面,看到网上一个人写了个三维DP,然后又想了想,其实,后面可以考虑用两个max 求最大值来表示,一个max来表示最后一个背包的容积,另一个max 来表示只有前m-1个背包时所获得最大物品数。具体代码如下:
1 #include <cmath> 2 #include <cstring> 3 #include <cstdlib> 4 #include <iostream> 5 #include <algorithm> 6 #include <memory> 7 #include <string> 8 #include <queue> 9 #include <map> 10 #include <stdio.h> 11 #include <vector> 12 #include <stack> 13 #include <fstream> 14 using namespace std; 15 16 int main() 17 { 18 int dp[25][25][25]; 19 int n,t,m,a[25]; 20 while(cin>>n>>t>>m) 21 { 22 for(int i=1;i<=n;i++) 23 cin>>a[i]; 24 memset(dp,0,sizeof(dp)); 25 for(int i=1;i<=m;++i) // 前i个背包 26 { 27 for(int j=1;j<=n;++j) // 前j件物品 28 { 29 for(int k=0;k<=t;++k) // 容量为k 30 { 31 if(k-a[j]>=0) // 放入 32 { 33 dp[i][j][k]=max(max(dp[i][j-1][k],dp[i][j-1][k-a[j]]+1),dp[i-1][j][t]); // 放入当前背包 34 35 } 36 else // 丢弃 37 dp[i][j][k]=max(max(dp[i][j-1][k],0),dp[i-1][j][t]); 38 //cout<<i <<" 个背包. "<<j<<" 件物品. "<<k<<" 容量 "<<dp[i][j][k]<<endl; 39 } 40 } 41 // 42 } 43 cout<<dp[m][n][t]<<endl; 44 } 45 return 0; 46 }
时间: 2024-10-07 00:48:41