CH 5E07 划分大理石 多重背包

版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/88862900

title

CH 5E07
描述

有价值分别为1…6的大理石各a[1…6]块,现要将它们分成两部分,使得两部分价值之和相等,问是否可以实现。其中大理石的总数不超过20000。

输入格式

有多组数据!
所以可能有多行
如果有0 0 0 0 0 0表示输入文件结束
其余的行为6个整数

输出格式

有多少行可行数据就有几行输出
如果划分成功,输出Can,否则Can’t

样例输入

4 7 4 5 9 1
9 8 1 7 2 4
6 6 8 5 9 2
1 6 6 1 0 7
5 9 3 8 8 4
0 0 0 0 0 0

样例输出

Can’t
Can
Can’t
Can’t
Can

analysis

这题竟然没有容积,怪不得写的那么难受。。。。。其实就是个简单的板子一套,然而我。。。。。。好了,不说了,,,,,,,,。。。。。。。。。。。。。。。。。。。。。。

扫描二维码关注公众号,回复: 5698754 查看本文章

code

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e4+10;
template<typename T>inline void read(T &x)
{
	x=0;
	T f=1, ch=getchar();
	while (!isdigit(ch) && ch^'-') ch=getchar();
	if (ch=='-') f=-1, ch=getchar();
	while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
	x*=f;
}
int num[7],sum,f[maxn*6],w[maxn*6];
int main()
{
	while (1)
	{
		memset(num,0,sizeof(num));
		sum=0;
		for (int i=1; i<=6; ++i)
			read(num[i]),sum+=num[i]*i;
		if (!sum) break;
		int m=sum>>1,tot=0;
		if (sum&1)
		{
			puts("Can't");
			continue;
		}
		for (int i=1; i<=6; ++i)
		{
			int tmp=0;
			for (int j=1; (j<<1)<=num[i]; j<<=1)
				w[++tot]=j*i,tmp+=j;
			w[++tot]=i*(num[i]-tmp);
		}
		f[0]=1;
		for (int i=1; i<=tot; ++i)
			for (int j=m; j>=w[i]; --j)
				f[j]|=f[j-w[i]];
		if (!f[m])
			puts("Can't");
		else
			puts("Can");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/huashuimu2003/article/details/88862900
今日推荐