csp-何以包邮:回溯错误
本人动态规划初学者,搞定01背包问题后尝试解决何以包邮的问题,并且成功解决了问题,得到了100分,但是我想通过回溯来确定选择的商品,却始终得到错误答案。
这是没有加回溯的代码,得到了满分
#include<iostream>
using namespace std;
int min(int a, int b) {
if (a >= b)
return b;
else
return a;
}
int dp[31][300001] = { 0 };
int main() {
int n, P;
cin >> n >> P;
int p[31];
for (int i = 1; i <= n; i++) {
cin >> p[i];
}
for(int i=0;i<=n;i++){
for (int c = 0; c <= P; c++) {
if (i == 0 && c == 0)
dp[i][c] = 0;
else if (i == 0 && c != 0)
dp[i][c] = 300002;
else if (i != 0 && c == 0)
dp[i][c] = 0;
else {
int m1 = dp[i - 1][c];
int m2;
if (c - p[i] > 0) //注意该特殊情况的处理(易错)
m2 = dp[i - 1][c - p[i]] + p[i];
else
m2 = p[i];
dp[i][c] = min(m1, m2);
}
}
}
cout << dp[n][P] << endl;
return 0;
}
这是添加了回溯的代码
//csp:何以包邮
#include<iostream>
using namespace std;
int dp[31][300001] = { {0} };
int rec[31][300001] = { {0} };
int main() {
int n, P;
cin >> n >> P;
int p[31];
for (int i = 1; i <= n; i++) {
cin >> p[i];
}
for(int i=0; i <= n; i++){
for (int c = 0; c <= P; c++) {
if (i == 0 && c == 0) {
dp[i][c] = 0;
rec[i][c] = 0;
}
else if (i == 0 && c != 0)
dp[i][c] = 300002;
else if (i != 0 && c == 0)
dp[i][c] = 0;
else {
int m1 = dp[i - 1][c];
int m2;
if (c - p[i] > 0)
m2 = dp[i - 1][c - p[i]] + p[i];
else
m2 = p[i];
if (m1 >= m2) { //填表以+记录追踪
dp[i][c] = m2;
rec[i][c] = 1;
}
else {
dp[i][c] = m1;
rec[i][c] = 0;
}
}
}
}
cout << dp[n][P] << endl;
//追踪
cout << "选择的商品是:";
for (int i = n, c = P; i > 0 && c > 0;) {
if (rec[i][c] == 1) {
cout << i<<' ';
i -= 1;
c -= p[i];
}
else {
i -= 1;
}
}
return 0;
}
拿csp中第一个用例来说
此处,选择的商品应该是:3 1,没有2,然后我把判断商品是否选择的数组全部输出来,结果四个全是1,希望大家可以看一下,指出我的错误与不足之处。