P1537 弹珠

P1537 弹珠

题目描述

玛莎和比尔各自有自己的弹珠收藏。他们想重新分配收藏品,使两人能平等拥有弹珠。如果所有的弹珠的价值相同,那么他们就可以平分。但不幸的是,有一些弹珠更大,或者更美丽,所以,玛莎和比尔给每个弹珠一个 \(1\)\(6\) 的价值。现在他们想平分这些弹珠,使每个人得到的总价值相同。不幸的是,他们发现,他们可能无法以这种方式分弹珠(即使弹珠的总价值为偶数)。例如,如果有一个价值为 \(1\)、一个价值为 \(3\) 和两个价值为 \(4\) 的弹珠,这样他们就不能把弹珠分为价值相等的两部分。因此,他们想要你写一个程序,告诉他们是否能将所有弹珠分成价值相等的两部分。

输入格式

输入文件有若干行,行中包含六个非负整数 \(N_1,\cdots,N_6\),其中 \(N_i\) 是价值为 \(i\) 的弹珠的个数。最大弹珠总数将达到 \(2\times 10^4\)

输入文件的最后一行是 0 0 0 0 0 0。不要处理这一行。

输出格式

对于每一组数据,输出 Collection #k:\(k\) 为输出的是第几组,接着是 Can be divided.Can't be divided.

每一组输出后多打一个空行。可以参考样例。

输入输出样例 #1

输入 #1

1 0 1 2 0 0 
1 0 0 0 1 1 
0 0 0 0 0 0

输出 #1

Collection #1:
Can't be divided.

Collection #2:
Can be divided.

这题很容易发现是一个可行性背包,但是如果我们直接这么做的话,我们的世间复杂度是 \(O(sumval\times n)\),这个显然是不行的,我们使用 bitset 优化一下就行,这样可以在复杂度上处以一个 \(w\),这样就能过了。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int MN=120000;
bitset <MN> dp;
int a1, a2, a3, a4, a5, a6, cnt=0;
int main(){
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	while(cin>>a1>>a2>>a3>>a4>>a5>>a6){
        if(a1==0&&a2==0&&a3==0&&a4==0&&a5==0&&a6==0) break;
		dp.reset(); dp.set(0,1); int sum=0;
		sum+=a1*1+a2*2+a3*3+a4*4+a5*5+a6*6;
		for(int i=1; i<=a1; ++i) dp|=(dp<<1);
		for(int i=1; i<=a2; ++i) dp|=(dp<<2);
		for(int i=1; i<=a3; ++i) dp|=(dp<<3);	
		for(int i=1; i<=a4; ++i) dp|=(dp<<4);
		for(int i=1; i<=a5; ++i) dp|=(dp<<5);
		for(int i=1; i<=a6; ++i) dp|=(dp<<6);
		cout<<"Collection #"<<++cnt<<":\n";
		if(sum%2==1||dp.test(sum/2)==0){
			cout<<"Can't be divided.\n";
		}else{
			cout<<"Can be divided.\n";
		}
		cout<<'\n';
	}
	return 0;
}
posted @ 2025-08-22 08:31  BaiBaiShaFeng  阅读(20)  评论(0)    收藏  举报
Sakana Widget右下角定位