首页 > 其他分享 >P1466 [USACO2.2] 集合 Subset Sums

P1466 [USACO2.2] 集合 Subset Sums

时间:2024-08-18 14:48:17浏览次数:4  
标签:Subset cout int 子集合 P1466 Sums long 划分 集合

题目描述

对于从 \(1\sim n\) 的连续整数集合,能划分成两个子集合,且保证每个集合的数字和是相等的。举个例子,如果 \(n=3\),对于 \(\{1,2,3\}\) 能划分成两个子集合,每个子集合的所有数字和是相等的:

\(\{3\}\) 和 \(\{1,2\}\) 是唯一一种分法(交换集合位置被认为是同一种划分方案,因此不会增加划分方案总数)
如果 \(n=7\),有四种方法能划分集合 \(\{1,2,3,4,5,6,7 \}\),每一种分法的子集合各数字和是相等的:

\(\{1,6,7\}\) 和 \(\{2,3,4,5\}\)
\(\{2,5,7\}\) 和 \(\{1,3,4,6\}\)
\(\{3,4,7\}\) 和 \(\{1,2,5,6\}\)
\(\{1,2,4,7\}\) 和 \(\{3,5,6\}\)

给出 \(n\),你的程序应该输出划分方案总数。

解题思路

  1. 如果用next_permutation找组合会TLE,所以用DP
  2. 1<=n<=39 打表出省一 (doge
  3. 如果1 ~ n 的和是奇数,答案肯定是0
  4. 定义状态:f[s]=将序列分为两部分,每部分的和为s,(计入重复,所以最后cout要/2)
  5. 状态转移方程: if (j >= i) f[j] += f[j - i];
  6. 初始化:f[0] = 1;

带马(暴力+正解+打表)

暴力

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
int a[40];
int c[40];
signed main() {
	cin >> n;
	if ((n * (n + 1) / 2) & 1) {
		cout << 0 << ",";
		return 0;
	}
	fill(a + 1, a + n + 1, 0);
	iota(a + 1, a + n + 1, 1);
	int ans = 0;
	for (int l = 0; l <= n; l++) {
		fill(c + 1, c + n + 1, 0);
		int pos = n;
		for (int i = 0; i < l; i++) {
			c[pos--] = 1;
		}
		do {
			int s1 = 0, s2 = 0;
			for (int i = 1; i <= n; i++) {
				if (c[i]) {
					s1 += a[i];
				} else {
					s2 += a[i];
				}
			}
			if (s1 == s2) {
				ans++;
			}
		} while (next_permutation(c + 1, c + n + 1));
	}
	cout << ans / 2 << ",";
	return 0;
}

正解

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
int f[1000];
signed main() {
	cin >> n;
	int s = n*(n + 1) / 2;
	if (s & 1) {
		cout << 0;
		return 0;
	}
	s /= 2;
	f[0] = 1;
	for (int i = 1; i <= n; i++) {
		for (int j = s; j >= 1; j--) {
			if (j >= i) f[j] += f[j - i];
		}
	}
	cout << f[s] / 2;
	return 0;
}

打表

#include<bits/stdc++.h>
#define int long long
using namespace std;
int k[] = {0, 0, 0, 1, 1, 0, 0, 4, 7, 0, 0, 35, 62, 0, 0, 361, 657, 0, 0, 4110, 7636, 0, 0, 49910, 93846, 0, 0, 632602, 1199892, 0, 0, 8273610, 15796439, 0, 0, 110826888, 212681976, 0, 0, 1512776590};
signed main() {
	int n;
	cin >> n;
	cout << k[n];
	return 0;
}

标签:Subset,cout,int,子集合,P1466,Sums,long,划分,集合
From: https://www.cnblogs.com/algorithm-hu/p/18365644

相关文章

  • [AGC056D] Subset Sum Game
    [AGC056D]SubsetSumGame题面翻译一块黑板上写着\(n\)个整数。第\(i\)个整数记作\(a_i\)。保证\(n\)是偶数。此外,给定\(L,R\)。Alice和Bob在玩一个游戏。他们轮流操作,Alice先手。在每一轮中,玩家需要选择一个写在黑板上的数,并擦掉它。游戏会在\(n\)轮后结束。......
  • D. Round Subset
    原题链接题意选择\(k\)个数,使得\(\min(\sum2,\sum5)\)最大实施1.二维背包dp,使因数5和2达到某一值的最小选择个数,但是因子数量最多有3600,会T2.于是试着想能不能交换背包容量与价值?3.发现k最多只有200,好像可以细节最多有6000个五大约code#include<bits/st......
  • 题解:SP11469 SUBSET - Balanced Cow Subsets
    SP11469(折半搜索)题目大意:给出$N$个数,求可以被分成两个和相等的集合的子集数。思路分析:首先考虑朴素的DFS,每个数有三种情况:选为$A$集合,选为$B$集合,两个集合都不选。暴力DFS时间复杂度为$3^{20}$。观察到$N$很小,而$3^{10}$是可以通过本题的,于是考虑折半搜索。我......
  • 【CF1656H】Equal LCM Subsets
    【CF1656H】EqualLCMSubsets题意给定集合\(A\)和\(B\),从中选择两个子集\(A'\subseteqA,B'\subseteqB\)满足\(\operatorname{lcm}(A')=\operatorname{lcm}(B')\)。满足\(\lvertA\rvert,\lvertB\rvert\le10^3,A,B\le4\times10^{35}\)。......
  • [题解]AT_abc151_e [ABC151E] Max-Min Sums
    思路考虑将\(\max\)和\(\min\)的贡献分开计算。显然我们对这个序列进行一次排序不会影响最终的答案,因此我们可以先排序一下。然后有一个很经典的trick,就是你枚举每一个数\(x\),将\(x\)令为最大值(最小值)。因为我们先前排序过一次,因此我们可以轻易的计算出比\(x\)小(大)的......
  • D. Prefix Permutation Sums
    原题链接题解1.缺少一个前缀和,缺少在哪了?如果缺少在\(i<n\)的地方,则会出现一个两个数之和,即缺少两个数否则会只缺少一个数2.两个数之和可能大于\(n\),也可能不3.虽然\(a_i\)达到了\(1e18\)但是\(n\leq2e5\),所以可以用数组记录出现的数code#include<bits/stdc++.......
  • ABC 321 F #(subset sum = K) with Add and Erase
    题意有一个箱子,每次可以向里面添加或者拿走一个数,问每次操作过后,任选箱子里的数相加,总和等于k的方案数是多少。思路萌新算是学到新东西了,这其实是个可撤销背包的板题。我们先考虑一个问题:对于普通计数类dp,我们现在禁用某一个数i,我们现在想知道某一个数j有多少种方式表示(即dp......
  • LeetCode 974 Subarray Sums Divisible by K All In One
    LeetCode974SubarraySumsDivisiblebyKAllInOneLeetCode974能被K整除的子数组之和errosfunctionsubarraysDivByK(nums:number[],k:number):number{//-5/0/5letcount:number=0;//单个元素for(leti=0;i<nums.length;i++){......
  • [ABC238E] Range Sums
    原题链接题解把这里的数字看成间隔,不要看成点假设已知能和\(l\)组成区间的端点集合\(A\)和以\(r\)组成区间的端点集合\(B\),这时候加入一个以\(l,r\)为左右端点的区间,那么在加入区间\(l,r\)之后,这两个集合可以合并code#include<bits/stdc++.h>usingnamespacestd......
  • [LeetCode] 1863. Sum of All Subset XOR Totals
    TheXORtotalofanarrayisdefinedasthebitwiseXORofallitselements,or0ifthearrayisempty.Forexample,theXORtotalofthearray[2,5,6]is2XOR5XOR6=1.Givenanarraynums,returnthesumofallXORtotalsforeverysubsetofnums.......