其他分享
首页 > 其他分享> > 划分大理石_题解

划分大理石_题解

作者:互联网

原题链接

简明题意:

有价值分别为 1~6 的大理石各 a[1],a[2]...a[6] 块,现要将它们分成两部分,使得两部分价值之和相等,问是否可以实现,即两部分均为一半。
其中大理石的总数不超过 20000。
多组输入,并且只需判断能否实现目标。

思路:

本题由 硬币(Coins)的二进制方法衍生过来,这里一起讲解
由奇偶数不难看出,当石头总价值sum为偶数时,才符合题意;显然只是多重背包且物品种类已知;本题建议用二进制优化较为合适;另外,我们f[i]数组的含义是:恰好部分A的价值为i,且用bool即可,这是从题意出发所确定的;显然,当部分A价值=部分B时,部分A和部分B的价值为总价值一半,若能组合出总价值的一半,即f[sum/2]=true,那么就符合题意,反正不符题意。

Code:

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int s[10];
bool f[N];
vector<int> str;
int main(){
	while(cin >> s[1] >> s[2] >> s[3] >> s[4] >> s[5] >> s[6]){
		if(!s[1] && !s[2] && !s[3] && !s[4] && !s[5] && !s[6]) break;
		int sum = 0;
		str.clear();
		memset(f, 0, sizeof(f));
		for(int i = 1; i <= 6; i++){
			sum += s[i] *i;
			for(int p = 1; p <= s[i]; p *= 2){
				s[i] -= p;
				str.push_back(i * p);
			}
			if(s[i]) str.push_back(i * s[i]);
		}
		f[0] = true;
		for(auto t : str)
			for(int i = sum/2; i >= t; i--)
				f[i] |= f[i-t];
		if(f[sum / 2] && sum % 2 == 0) cout << "Can" << endl;
		else cout << "Can't" << endl;
	}
	return 0;
}

标签:题意,int,题解,sum,总价值,划分,&&,大理石,部分
来源: https://www.cnblogs.com/P32sx-qq1309267816-tel18081238250/p/16398511.html