题解 CH5E07 【划分大理石】

题目链接:Link

Problem

Solution

这题好难啊只需要判断能否拼接出sum/2即可,因为剩下的必然也是sum/2。。。
然后就可以愉快地多重背包了。。。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=20005;
int a[7],f[maxn*6],tot,Q[maxn*6],L,R;
void DP(int v,int t)
{
	for(int s=0;s<v;s++)
	{
		Q[L=R=1]=s;
		for(int j=s+v;j<=tot;j+=v)
		{
			while(L<=R&&(j-Q[L])/v>t) L++;
			if(L<=R) f[j]=f[Q[L]];
			while(L<=R&&f[j]>=f[Q[R]]) R--;
			Q[++R]=j;
		}
	}
}
int main()
{
	#ifdef local
	freopen("pro.in","r",stdin);
	#endif
	while(true)
	{
		tot=0;
		for(int i=1;i<=6;i++) { scanf("%d",&a[i]); tot+=a[i]*i; }
		if(tot==0) return 0;
		if(tot&1) { puts("Can't"); continue; }
		memset(f,0,sizeof(f));
		f[0]=1; tot/=2;
		for(int i=1;i<=6;i++) DP(i,a[i]);
		puts(f[tot]?"Can":"Can't");
	}
	return 0;
}
posted @ 2019-09-14 09:54  happyZYM  阅读(196)  评论(0编辑  收藏  举报