首页 > 其他分享 >题解:SP11469 SUBSET - Balanced Cow Subsets

题解:SP11469 SUBSET - Balanced Cow Subsets

时间:2024-07-15 20:20:37浏览次数:7  
标签:SUBSET 第一遍 Cow 记录 int 题解 dfs 搜索 DFS

SP11469(折半搜索)

题目大意:

给出 $N$ 个数,求可以被分成两个和相等的集合的子集数。

思路分析:

首先考虑朴素的 DFS,每个数有三种情况:选为 $A$ 集合,选为 $B$ 集合,两个集合都不选。暴力 DFS 时间复杂度为 $3^{20}$。

观察到 $N$ 很小,而 $3^{10}$ 是可以通过本题的,于是考虑折半搜索。

我们设前半部分搜索出来的两个集合和分别为 $A$、$B$,后半部分为 $D$、$C$,则 $A+D=B+C$。

变形可得 $A-B=C-D$。

所以我们只需要记录当前 DFS 搜出来的两个集合差为多少。

part1. 第一遍 DFS

首先 DFS 从 $1$ 到 $(1+N)\div 2$,记录当前搜出来两个集合的差,同时用状态压缩记录选了哪些数。搜完后用 vector 记录当前状态。

由于差可能很大或为负数,我们需要用 map 编号(也就是离散化)后加入 vector。

part2. 第二遍 DFS

和第一遍相似,DFS 从 $(1+N)\div 2 +1$ 到 $N$,记录的内容和第一遍相同。

搜完后在 vector 的对应位置记录答案。

DFS 代码:

void dfs(int a,int b,int c,int d){//a表示当前位置,b表示结束位置,c表示搜索出来的差,d表示状压后的状态
	if(a==b+1){
		if(a!=n+1){//第一遍 DFS 后记录答案
			if(!m[c])  m[c]=++p;
			v[m[c]].push_back(d);
		}
		else{//第二遍 DFS 后记录答案
			int t=m[c];
			for(auto i:v[t])
				vis[i|d]=1;
		}
		return ;
	}
	dfs(a+1,b,c,d);//枚举三种情况
	dfs(a+1,b,c+A[a],d|(1<<a));
	dfs(a+1,b,c-A[a],d|(1<<a));
}

part3. 计算答案

这部分比较简单,枚举 vis 数组中所有状态记录答案。

完整代码:

#include <bits/stdc++.h>
using namespace std;
int n,A[25],p,ans;
bool vis[2100000];
map<int,int> m;
vector<int> v[2100000];
void dfs(int a,int b,int c,int d){//a表示当前位置,b表示结束位置,c表示搜索出来的差,d表示状压后的状态
	if(a==b+1){
		if(a!=n+1){//第一遍 DFS 后记录答案
			if(!m[c])  m[c]=++p;
			v[m[c]].push_back(d);
		}
		else{//第二遍 DFS 后记录答案
			int t=m[c];
			for(auto i:v[t])
				vis[i|d]=1;
		}
		return ;
	}
	dfs(a+1,b,c,d);//枚举三种情况
	dfs(a+1,b,c+A[a],d|(1<<a));
	dfs(a+1,b,c-A[a],d|(1<<a));
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&A[i]);
	int mid=(1+n)>>1;
	dfs(1,mid,0,0);//第一次搜索
	dfs(mid+1,n,0,0);//第二次搜索
	for(int i=1;i<=(1<<n+1);i++)
		ans+=vis[i];//计算答案
	printf("%d",ans);
	return 0;
}

标签:SUBSET,第一遍,Cow,记录,int,题解,dfs,搜索,DFS
From: https://www.cnblogs.com/ywb-33/p/18303896

相关文章

  • P10720 [GESP202406 五级] 小杨的幸运数字 题解
    题意如果一个数的质因子中只有两个不同的数则输出\(1\),否则输出\(0\)。思路从第一个质因子遍历到\(sum\)的话很明显是\(O(nt)\)最大是\(n^{10}\)很明显会炸掉。所以遍历到\(sum\)是不行的,考虑正整数\(n\)最大的质因数是\(\sqrt{n}\)所以遍历到\(\sqrt{n}\)即......
  • 题解:SP10502 VIDEO - Video game combos
    大意构造一个长度为\(k\)(\(k\)是给定的)的串\(x\),使得对于\(∀1\leqi\leqn,s_i\)在\(x\)中的出现次数之和最大。输出这个最大值。思考考虑对\(s_i\)建AC自动机,然后dp。记\(dp[i][u]\)表示为长度为\(i\)的字符串,且当前已计算的节点是Trie上的编号为\(u......
  • 【题解】 [CSP-J 2021 T1] 分糖果
    题目描述题目大意给定正整数\(n\)、\(L\)、\(R\),求\(\max_{i\in\left[L,R\right]}{i\bmodn}\)。思路题目主要考察:分类讨论。众所周知,对于\(\forallx\),有$(x\bmodn)\in\left[0,n-1\right]$。可以分为两种情况讨论:如果\(\left\lfloor\frac{L......
  • 题解:CF1833F Ira and Flamenco
    思路因为要一个长度为\(m\)的,且最大与最小的元素之差小于等于\(m\)所以序列应为\(a_i,a_i+1,a_i+2\dots,a_i+m-1\),所以满足要求的序列之需要连续\(m\)个就行了,这个最开始排序,去重后用lower_bound求一下小于\(a_i+m-1\)的数有没有\(m\)个就行了。考虑满足要求序列的......
  • P8704 [蓝桥杯 2020 省 A1] 填空问题 题解
    题目传送门A.跑步训练我们经过仔细观察,可以发现每222分钟就会消耗300300......
  • P2754 [CTSC1999] 家园 / 星际转移问题题解
    开始时,将源点连一条权值为\(k\)的边到地球。然后以时间分层,从上一层的点连接到下一层的点,权值为飞船载人数量,并将代表月球的点连接到汇点。每加一层,在上一层的基础上进行增广,看能不能增加流量,如果流量变为\(k\),那么证明运送完成。可以证明枚举时间最多到\(1500\),图的点数不......
  • SP4063 MPIGS - Sell Pigs / P4638 [SHOI2011] 银行家题解
    考虑使用网络流。建立源点\(S\)和汇点\(T\)。每个人作为一个点,将它们与汇点\(T\)连接,权值为需要的猪的数量。然后对于每个人,如果和之前的某个人开了相同的猪圈,那么就将之前的那个人的点与这个人的点连接。如果猪圈还没有被开过,就从源点\(S\)连接这个点,权值为猪圈猪的初......
  • P1402 酒店之王题解
    考虑使用网络流。分为\(6\)层。第一层为源点。第二层为所有菜的点。第三层和第四层都表示人。(限制只能选择一个)。第五层为房子。第六层为汇点。#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;constintN=410,M=101000,INF=0x3f3f3f3......
  • AE莫名的小问题解决办法和基础的操作快捷键分享
    更多macOS实用教程,小白教学点击这里!AdobeAfterEffects,简称AE,是由Adobe公司开发的视频剪辑和设计软件。它是一款用于动画、视觉效果和电影合成的二维半动画软件,广泛应用于电影、电视和网络视频创作。AfterEffects主要用于创建动态图像和视觉特效,被誉为制作动态影像设计不可或......
  • 题解 P5270 无论怎样神树大人都会删库跑路
    题解P5270无论怎样神树大人都会删库跑路题意已经说得很清楚了,我们直接开始讲题。首先考虑一次只插入一个字符。问题只在于我们想要判断最后几个字符是否组成相同,即判断两个可重集合是否相等。这个需求很像字符串哈希的目的(快速判断两个字符串是否相等)。但集合怎么哈希呢?需求......