您的位置:首页 > 其它

Vijos - P1071 新年趣事之打牌

2014-08-19 17:54 232 查看


思路

先用背包求出能否凑成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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: