题意:
一个数n,及n个数,让你求n个数中取哪些数可更接近n
思路:
01背包,不过要打印路径。
打印路径的话,就看dp[i][j]是否=dp[i-1][j-a[i]]+a[i]],即是不是装了当前背包,装了就j-=a[i],这样从尾向头遍历并标记即可。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 2000;
int dp[N][N],a[N],ans[N];
int main() {
int n, t;
while (~scanf("%d", &t)) {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
memset(ans, 0, sizeof(ans));
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= t; j++) {
dp[i][j] = dp[i - 1][j];
if (j>=a[i])
dp[i][j] =max(dp[i][j], dp[i-1][j - a[i]] + a[i]);
}
}
int temp = t;
for (int i = n; i >= 0; i--) {
if (dp[i][temp] == dp[i-1][temp - a[i]] + a[i]) {
temp = temp - a[i];
ans[i] = 1;
}
}
for (int i = 1; i <= n; i++){
if (ans[i])
printf("%d ", a[i]);
}
printf("sum:%d\n", dp[n][t]);
}
return 0;
}