Hlg 1740 DP求路径且按最小字典序输出.cpp
题意:
给出n个石头的重量和得分,有一个为m的背包,问在m个背包里能装的最大得分是多少,并要求输出装入的石子编号..
如果有多个解则输出字典序最小的..
思路:
这个在背包九讲后面有提及..
主要是用一个二维数组path[i][j]表示当体积为j的时候第i件物品是否有被装入..
最后用一次循环根据if(path[i][tv]) {
ans[cnt++] = i;
tv -= v[i];
}
就可以求出路径并保存在ans里面了..
Tips:
注意找的时候应该是从i = n往前遍历..
而输出的时候应该是cnt~0
做这道题的过程中遇到一个问题就是:如果我是用二维数组来求01背包,那代码应该是
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h>
2 #include <cstring>
3 #include <algorithm>
4 using namespace std;
5
6 int v[110], w[110];
7 int dp[101][1010], path[100010], ans[110];
8 int main()
9 {
10 freopen("in.in", "r", stdin);
11 int T, n, m;
12 int cnt, sum;
13 scanf("%d", &T);
14 while(T--) {
15 scanf("%d %d", &n, &m);
16 memset(dp, 0, sizeof(dp));
17 memset(path, 0, sizeof(path));
18 cnt = 0;
19 int res = 0;
20 for(int i = 1; i <= n; ++i)
21 scanf("%d %d", &v[i], &w[i]);
22 for(int i = 1; i <= n; ++i) {
23 for(int j = m; j >=v[i]; --j) {
24 dp[i][j] = max(dp[i-1][j-v[i]]+w[i], dp[i-1][j]);
25 }
26 for (int j=v[i]-1;j>=0; j--)dp[i][j] = dp[i-1][j];
27 }
28 printf("%d\n", dp[n][m]);
29 }
30 return 0;
31 }
因为i+1的体积可能比i小..
但是每次更新都是从v[i]~V..
所以应该把0~v[i]都加到dp[i][0~v[i]]里..
Code:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 int v[110], w[110], dp[100010], ans[110]; 7 bool path[110][10010]; 8 int main() 9 { 10 // freopen("in.txt", "r", stdin); 11 int T, n, m; 12 int cnt, sum; 13 scanf("%d", &T); 14 while(T--) { 15 scanf("%d %d", &n, &m); 16 memset(dp, 0, sizeof(dp)); 17 memset(path, 0, sizeof(path)); 18 cnt = 0; 19 for(int i = 1; i <= n; ++i) 20 scanf("%d %d", &v[i], &w[i]); 21 22 for(int i = 1; i <= n; ++i) { 23 for(int j = m; j >= v[i]; --j) { 24 int t = dp[j]; 25 dp[j] = max(dp[j-v[i]]+w[i], dp[j]); 26 path[i][j] = dp[j] == t?false:true; 27 } 28 } 29 int tv = m; 30 for(int i = n; i > 0; --i) 31 if(path[i][tv]) { 32 ans[cnt++] = i; 33 tv -= v[i]; 34 } 35 36 printf("%d\n", dp[m]); 37 for(int i = cnt-1; i >= 0; --i) 38 printf("%d%c", ans[i], i == 0?'\n':' '); 39 } 40 return 0; 41 }
链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1740