2016-4-25 完美世界-实习--小萌的包裹

一开始看到这题就认为应该用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 }
View Code
原文地址:https://www.cnblogs.com/wen-ge/p/5442095.html