# 【动态规划】Gentlemen

## 1244. Gentlemen

Time Limit: 0.5 second
Memory Limit: 16 MB
Let's remember one old joke:
Once a gentleman said to another gentleman:
— What if we play cards?
— You know, I haven't played cards for ten years…
— And I haven't played for fifteen years…
So, little by little, they decided to resurrect their youth. The first gentleman asked a servant to bring a pack of cards, and before starting playing out weighed in his hand the pack.
— It seems to me, one card is missing from the pack… — he said and gave the pack to the other gentleman.
— Yes, the nine of spades, — the man agreed.
An incomplete pack of cards is given. The program should determine which cards are missing.

### Input

The first line contains a positive integer, which is the weight in milligrams of the given incomplete pack. The second line contains an integer N, 2 ≤ N ≤ 100 — the number of cards in the complete pack. In the next N lines there are integers from 1 to 1000, which are the weights of the cards in milligrams. It's guaranteed that the total weight of all cards in the complete pack is strictly greater than the weight of the incomplete pack.

### Output

If there is no solution, then output the single number 0. If there are more than one solutions, then you should write −1. Finally, if it is possible to determine unambiguously which cards are missing in the incomplete pack as compared to the complete one, then output the numbers of the missing cards separated with a space in ascending order.

### Samples

input output
270
4
100
110
170
200

2 4

270
4
100
110
160
170

-1

270
4
100
120
160
180

0


#include <algorithm>
#include <cstdlib>
#include <cstdio>
using std::sort;
long weight;
long n;

struct node
{
long w;
long i;
};
long card[110];
unsigned char f[101][100001];
long ans[110];
long top = 0;

bool cmpr(const node& a,const node& b)
{
return a.w < b.w;
}

inline long GCD(long a,long b)
{
while (b)
{
long tmp = b;
b = a%b;
a = tmp;
}
return a;
}

int main()
{
scanf("%ld%ld",&weight,&n);

scanf("%ld",card+1);
weight -= card[1];
long gg = card[1];
for (long i=2;i<n+1;i++)
{
scanf("%ld",card+i);
if (card[i])
{
gg = GCD(gg,card[i]);
weight -= card[i];
}
}
weight = -weight;
if (weight == 0)
{
printf("-1");//???
return 0;
}
gg = GCD(gg,weight);
for (long i=1;i<n+1;i++)
card[i] /= gg;
weight /= gg;

f[1][0] = 1;
for (long i=1;i<n+1;i++)
{
for (long j=0;j<weight+1;j++)
f[i+1][j] = 0;
for (long j=0;j<weight+1;j++)
{
if (j+card[i] < weight+1)
{
if (f[i+1][j+card[i]]+f[i][j] > 255)
f[i+1][j+card[i]] = 255;
else
f[i+1][j+card[i]] += f[i][j];
}
if (f[i+1][j] + f[i][j] > 255)
f[i+1][j] = 255;
else
f[i+1][j] += f[i][j];
}
}

if (f[n+1][weight] == 0)
printf("0");
else if (f[n+1][weight] > 1)
printf("-1");
else
{
long j = weight;
for (long i=n+1;i>1;i--)
{
if (f[i-1][j-card[i-1]])
{
ans[++top] = i-1;
j = j-card[i-1];
}
}
for (long i=top;i>0;i--)
printf("%ld ",ans[i]);
}
return 0;
}


• 本文已收录于以下专栏：

## 【URAL 1244】Gentlemen（DP+记录路径）

【URAL 1244】Gentlemen（DP+记录路径）题目大意： n张卡片，每张有价值。给出一个价值V，问是否有唯一组合方式组合出V。 有的话输出不在组合里的卡牌编号，没有的话输出0，多解输出...
• ChallengerRumble
• 2016年10月10日 21:04
• 495

## HDOJ 4126 Bazinga (字符串预处理)

Bazinga Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Su...
• helloiamclh
• 2015年11月13日 20:06
• 421

## 测试集(2)-words

• longronglin
• 2006年11月26日 16:11
• 16494

## URAL 1244. Gentlemen

• u012891242
• 2014年08月21日 20:00
• 484

## Gentlemen经验积累

1、送佛送到西(我送你/们到楼下吧)
• chlhp
• 2009年10月25日 00:52
• 327

## URAL 1244 Gentlemen

• youthinkwu
• 2015年02月19日 00:35
• 120

## Timus 1244. Gentlemen

01背包，霸气不解释！ 哦，错了，是寀蒻不解释。。。 有两个点，第一输入的那些值不一定是升序的，回溯的时候要注意退出点 第二，0，2，1，1 这样的数据注意别被坑。。。 7月刷了20题...
• dyhu083
• 2013年07月20日 16:12
• 375

## 教你彻底学会动态规划——入门篇

• baidu_28312631
• 2015年08月11日 13:26
• 102074

## 如何实现动态规划？——TWO

• f_zyj
• 2016年03月01日 22:11
• 880

## 动态规划总结——经典问题总结

• qfikh
• 2016年07月19日 13:08
• 2766

举报原因： 您举报文章：【动态规划】Gentlemen 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)