【动态规划】Gentlemen

原创 2012年03月30日 10:03:50

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


题目比较简单,但是维护方案比较麻烦,因为空间限制是16MB。。。网上的题解方法是一些钻空子的方法,比较巧妙。。

但是其实我的钻空子更钻我觉得。


题目可以看出,答案之和f[i][j]是等于零,还是等于一,还是大于一有关,输出方案只和f[i][j]是否等于一有关。

因此用不着long int,我开了最小的unsigned char。

如果f[i][j]大于255了,就把它设为是255,反正也不会影响答案。


这道题我用了GCD,来缩小规模,可能效果不好就是了。。对于小数据可能有用,但是大数据我猜一定起了反效果,最大公约数大于1的可能性太小了、、


#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
  • 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
  • helloiamclh
  • 2015年11月13日 20:06
  • 421

测试集(2)-words

 aa.ma.mabandonabandonabattoirabilityabilityableableabnormalabnormalaboardaboardaboutaboutaboveabove...
  • longronglin
  • longronglin
  • 2006年11月26日 16:11
  • 16494

URAL 1244. Gentlemen

滚动数组+
  • u012891242
  • u012891242
  • 2014年08月21日 20:00
  • 484

Gentlemen经验积累

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

URAL 1244 Gentlemen

给出扑克丢失后的总重量,给出几张扑克的编号和它们的重量,让你指出丢失了哪几张扑克。如果无解输出0,多种丢失方式输出-1,只有一种丢失方式则输出丢失的牌的编号。 方法:dp[i]表示重量为i的组合方式...
  • youthinkwu
  • youthinkwu
  • 2015年02月19日 00:35
  • 120

Timus 1244. Gentlemen

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

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

动态规划相信大家都知道,动态规划算法也是新手在刚接触算法设计时很苦恼的问题,有时候觉得难以理解,但是真正理解之后,就会觉得动态规划其实并没有想象中那么难。网上也有很多关于讲解动态规划的文章,大多都是叙...
  • baidu_28312631
  • baidu_28312631
  • 2015年08月11日 13:26
  • 102074

如何实现动态规划?——TWO

忙碌了一天,是时候继续动态规划的问题了,昨天写了一些对动态规划的入门理解,尽管我文笔略差,但是自我感觉打得比方还是比较形象的;同时也转载了一个讲述动态规划的博文,但是在今天通读后,感觉这篇文章优点和缺...
  • f_zyj
  • f_zyj
  • 2016年03月01日 22:11
  • 880

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

动态规划总结——经典问题总结 本文着重讨论状态是如何表示,以及方程是怎样表示的。当然,还附上关键的,有可能作为模板的代码段。但有的代码的实现是优化版的。 经典问题总结 最长上升子序列(LIS) 问题描...
  • qfikh
  • qfikh
  • 2016年07月19日 13:08
  • 2766
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【动态规划】Gentlemen
举报原因:
原因补充:

(最多只允许输入30个字)