ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

划分大理石_题解

2022-06-21 22:01:28  阅读:121  来源: 互联网

标签:题意 int 题解 sum 总价值 划分 && 大理石 部分


原题链接

简明题意:

有价值分别为 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有