思路
先用背包求出能否凑成left,还要一边记录路径。
然后递归打印路径即可。
二维数组开不下,滚一下就行。
代码
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define MP(a, b) make_pair(a, b)
const int MAXN = 100000 + 10;
const int INF = 0x3f3f3f3f;
int dp[MAXN], card[110], path[MAXN];
bool first = true;
void PrintAns(int num)
{
if (path[num] == -1)
return;
int x = path[num];
PrintAns(num - card[x]);
if (first)
printf("%d", x), first = false;
else
printf(" %d", x);
}
int main()
{
//freopen("input.txt", "r", stdin);
int w, n, i, j, left, sum = 0;
scanf("%d%d", &w, &n);
for (i = 1; i <= n; i++)
{
scanf("%d", &card[i]);
sum += card[i];
}
left = sum - w;
dp[0] = 1;
path[0] = -1;
for (i = 1; i <= n; i++)
for (j = sum; j >= card[i]; j--)
{
if (!dp[j] && dp[j - card[i]] > 0) //这个状态还没达到并且将要达到
path[j] = i;
dp[j] += dp[j - card[i]];
}
if (dp[left] > 1)
{
printf("-1\n");
return 0;
}
if (!dp[left])
{
printf("0\n");
return 0;
}
PrintAns(left);
puts("");
return 0;
}