[CSP-S模拟测试]:毛一琛(meet in the middle)

题目描述

  历史学考后,$MYC$和$ztr$对答案,发现选择题他们没有一道选的是一样的。最后他们都考了个$C$。现在问题来了,假设他们五五开,分数恰好一样(问答题分数也恰好一样,只考虑选择题)。已知考题是$N$道选择题(第$i$题分数为$M(i)$)。问$ztr$和$MYC$做对的题的并有多少种可能?众所周知,历史学考选择题有$25$题,但是$MYC$为了给你降低难度,$n$不超过$20$。
  一句话题意:有多少个非空子集,能划分成和相等的两份。

原题见:$USACO\ 2012\ OPEN\ GOLD\ subsets$


输入格式

第一行:整数$N$
第$2..1+N$行:第$i+1$行是$M(i)$


输出格式

一个整数表示答案


样例

样例输入:

4
1
2
3
4

样例输出:

3


数据范围与提示

样例解释:

有三个合法的集合:$\{1,2,3\}$,它可以被分割成$\{1,2\}$和$\{3\}$,集合$\{1,3,4\}$,它可以被分割为$\{1,3\}$和$\{4\}$;集合$\{1,2,3,4\}$可以被分割成子集$\{1,4\}$和$\{2,3\}$。

数据范围:

不要问我为什么数据范围这么奇怪。。。因为要给大家送分。。。


题解

又被题意坑死……

先来解释一下题意,题目是要统计所有子集中可以被等分的集合(如果有多种方案,不能重复统计)。

$\Theta(n^3)$暴力应该都会打(分为不选,给一个人,给另一个人)。

但是这样显然过不去,考虑$meet\ in\ the\ middle$,先枚举左边$3^{\frac{N}{2}}$,再枚举右边$3^{\frac{N}{2}}$即可。

时间复杂度:$\Theta(6^{\frac{N}{2}})$。、

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
const int mod=30000019;
struct rec{int nxt,to,now,val;}e[59050];
int head[300000019],cnt;
int N;
int a[21];
bool vis[1100][1100],v[21];
int ans;
void insert(int now,int val)
{
	int key=(val%mod+mod)%mod;
	for(int i=head[key];i;i=e[i].nxt)
		if(e[i].now==now&&e[i].val==val)return;
	e[++cnt].nxt=head[key];
	e[cnt].now=now;
	e[cnt].val=val;
	head[key]=cnt;
}
int ask(int now,int val)
{
	int key=(val%mod+mod)%mod,res=0;
	for(int i=head[key];i;i=e[i].nxt)
		if(e[i].val==val&&!vis[e[i].now][now])
		{
			vis[e[i].now][now]=1;
			res++;
		}
	return res;
}
void dfs1(int x,int w)
{
	if(x>N/2)
	{
		int now=0;
		for(int i=1;i<=N/2;i++)now=now<<1|v[i];
		insert(now,w);
		return;
	}
	v[x]=0;dfs1(x+1,w);
	v[x]=1;dfs1(x+1,w+a[x]);
	v[x]=1;dfs1(x+1,w-a[x]);
}
void dfs2(int x,int w)
{
	if(x>N)
	{
		int now=0;
		for(int i=N/2+1;i<=N;i++)now=now<<1|v[i];
		ans+=ask(now,w);
		return;
	}
	v[x]=0;dfs2(x+1,w);
	v[x]=1;dfs2(x+1,w+a[x]);
	v[x]=1;dfs2(x+1,w-a[x]);
}
int main()
{
	scanf("%d",&N);
	for(int i=1;i<=N;i++)scanf("%d",&a[i]);
	dfs1(1,0);
	dfs2(N/2+1,0);
	printf("%d",ans-1);
	return 0;
}


rp++

原文地址:https://www.cnblogs.com/wzc521/p/11669903.html

时间: 2024-08-30 08:31:47

[CSP-S模拟测试]:毛一琛(meet in the middle)的相关文章

「10.13」毛一琛(meet in the middle)&#183;毛二琛(DP)&#183;毛三琛(二分+随机化???)

A. 毛一琛 考虑到直接枚举的话时间复杂度很高,我们运用$meet\ in\ the\ middle$的思想 一般这种思想看似主要用在搜索这类算法中 发现直接枚举时间复杂度过高考虑枚举一半另一半通过其他算法统计,保证两边互不影响 今天的题我们考虑枚举先枚举左半部分,然后每个物品有三种取值情况 选入A集合,选入B集合,不选,系数不同 考虑完左半部分再去考虑右半部分,那么我们可以用哈系表先从将左半部分的答案统计出来 然后右半部分查询他的相反数注意去重 也可以用将两边状态都用结构体存下来 注意去重 思

模拟测试20191013

T1:毛一琛 上来有显然的$3^{n}$暴力,考虑优化 利用$meet \ in \ middle $思想,我们枚举这个数左边的子集插入$hashmap$,再枚举右边的子集并查询左边就好了 T2:毛二琛 根据题意发现这是一个有限制的相邻交换问题 我们可以发现只需要对相邻的数进行限制即可构造出所有限制状况 然后简单dp就好了,前缀和优化一下 详情请看$skyh$大神的博客(他没写就去谴责他 T3:毛三琛 暴力$O(n^{2}logn)$,利用随机化和减枝可以优化到$O(nlog^{2})$ 原文地

「题解」:毛一琛/$cow$ $subsets$

问题 A: 毛一琛/$cow$ $subsets$ 时间限制: 1 Sec  内存限制: 512 MB 题面 题面谢绝公开. 题解 题名貌似是个大神??看起来像是签到题然后就死了. 首先$O(3^n)$算法显然.也显然过不去$20$的测试点. 正解是赫赫有名的$meet$ $in$ $the$ $middle$算法.数据在40以内的都能用$meet$ $in$ $the$ $middle$?? 对于两半路径,可以拼起来并且构成合法答案的条件是两人获得的分数相同. 所以一个比较聪明的办法是,不去记

[考试反思]1013csp-s模拟测试71:徘徊

分差好大...但是从排名上看也许还可以接受? 不算太炸 但是这个还是算了吧... 其实状态不是很好. T1不会,打的搜索,想到一个剪枝但是感觉没什么用,所以没打. 考后打上,85了...打上另一个就90了... T3已经想到正解思路了,但是不完善 T2想到正解,但是没有证明它是树形,于是没有打... 又说不完,晚上又要考,改善状态. T1:毛一琛 又是meet in miiddle.又没想到. 其实也就是双向搜索,然后hash_map查状态即可. 打的lower_bound,多了一个log.勉强

模拟测试(vj)

做这份模拟测试,已经崩溃了,英文看不懂,题意理解错.到结束了只a了第一题,人生陷入了低谷,于是花了一天的时间终于把不会的弄明白了,在这里写一份总结~ T1,简单的模拟,如果打枪打中一支鸟,将这个位置设为0,并向两边扩散,注意这个位置一定要有鸟. 代码~ #include<bits/stdc++.h> using namespace std; int a[30000]; int n,m; int main() { cin>>n; for(int i=1;i<=n;i++) ci

Android单元测试与模拟测试详解

测试与基本规范 为什么需要测试? 为了稳定性,能够明确的了解是否正确的完成开发. 更加易于维护,能够在修改代码后保证功能不被破坏. 集成一些工具,规范开发规范,使得代码更加稳定( 如通过 phabricator differential 发diff时提交需要执行的单元测试,在开发流程上就可以保证远端代码的稳定性). 2. 测什么? 一般单元测试: 列出想要测试覆盖的异常情况,进行验证. 性能测试. 模拟测试: 根据需求,测试用户真正在使用过程中,界面的反馈与显示以及一些依赖系统架构的组件的应用测

微信在线信息模拟测试工具(基于Senparc.Weixin.MP)

目前为止似乎还没有看到过Web版的普通消息测试工具(除了官方针对高级接口的),现有的一些桌面版的几个测试工具也都是使用XML直接请求,非常不友好,我们来尝试做一个“面向对象”操作的测试工具. 测试工具在线DEMO:http://weixin.senparc.com/SimulateTool Senparc.Weixin.MP是一个开源的微信SDK项目,地址:https://github.com/JeffreySu/WeiXinMPSDK (其中https://github.com/Jeffrey

css Hack,用IE11模拟测试的,条件注释要找真IE去测,模拟的无效

<!DOCTYPE html> <!--[if lt IE 7 ]> <html class="ie6 ie"> <![endif]--> <!--[if IE 7 ]> <html class="ie7 ie"> <![endif]--> <!--[if IE 8 ]> <html class="ie8 ie"> <![endif]

2016年上半年软考真题在线模拟测试,提前知晓你的成绩

2016年上半年软考于5月21日结束了,考试完想知道结果的急切心理,几乎每个经历过上学时代的人都能深刻体验到.如果你想知道你考的怎么样,如果你想要提前知道你的成绩,如果你想知道你哪个地方出错了,如果你想知道你哪个地方知识掌握的不够想要更深入的去理解,那就来希赛软考学院吧!希赛软考学院提供2016年上半年软考真题在线模拟测试,有标准的参考答案,有专业老师的解析视频,让你提前知晓你的成绩,让你再次巩固学习. 希赛授课专家介绍 张友生,计算机应用技术博士,软考培训教程系列丛书主编,考试指定教材<系统分