bzoj2064: 分裂(集合DP)
......咸鱼了将近一个月,因为沉迷ingress作业越来越多一直没时间搞OI呜呜呜
题目大意:有一个初始集合(n个元素)和一个目标集合(m个元素)(1<=n,m<=10),两个操作
操作①将集合里的两个数合成一个数
操作②将集合的一个数分成两个数
问对初始集合最少进行几次操作可以到达目标集合
...从来没做过集合DP题,看见这题一脸懵逼>_<
看了题解之后目瞪口呆,思路好神,又学会了新技巧(可能是我以前比较傻才不会QAQ
显然最多的次数就是将初始集合全部合成一个数然后再分成目标集合,也就是次数上界为n+m-2
如果我们可以找到初始集合的某个子集的元素和与目标集合的某个子集的元素和相等,那么我们可以少合一次,少分一次,也就是说我们每多找到一个元素和相等的子集我们的次数就可以-2。换句话说把初始集合和目标集合分成尽量多的子集让这些子集都能对应(子集元素和相等),如果能分成x个子集那么次数就是n+m-2x
所以问题转化成怎么分最多子集能相对应。f[S1][S2]为把S1和S2最多能分成几个能相对应的子集(子集元素和相等)。
当S1的元素和!=S2的元素和,就没法用上所有元素分成相对应的子集,那我们就枚举S1中的元素i或S2中的一个元素j,就有f[S1][S2]=max(f[S1^i][S2],f[S1][S2^j])
当S1的元素和==S2的元素和,我们可以用上全部元素,在这时候我们要是去掉其中一个元素,肯定会少一个子集,于是我们还是枚举S1中的元素i或S2中的一个元素j,就有f[S1][S2]=max(f[S1^i][S2],f[S1][S2^j])+1
新技巧:......原来枚举子集用二进制枚举就可以了,以前我怎么这么傻QAQ
代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
using namespace std;
int n,m,sum1[],sum2[],f[][];
int lowbit(int x){return x&-x;}
int main()
{
scanf("%d",&n);
for(int i=;i<n;i++)scanf("%d",&sum1[<<i]);
scanf("%d",&m);
for(int i=;i<m;i++)scanf("%d",&sum2[<<i]);
for(int i=;i<(<<n);i++)sum1[i]=sum1[i^lowbit(i)]+sum1[lowbit(i)];
for(int i=;i<(<<m);i++)sum2[i]=sum2[i^lowbit(i)]+sum2[lowbit(i)];
for(int i=;i<(<<n);i++)
for(int j=;j<(<<m);j++)
{
for(int k=;k<max(n,m);k++)
{
if(i&(<<k))f[i][j]=max(f[i^(<<k)][j],f[i][j]);
if(j&(<<k))f[i][j]=max(f[i][j^(<<k)],f[i][j]);
}
if(sum1[i]==sum2[j])f[i][j]++;
}
printf("%d\n",n+m-*f[(<<n)-][(<<m)-]);
}
bzoj2064: 分裂(集合DP)的更多相关文章
- bzoj2064分裂(dp)
题目大意: 给定一个初始集合和目标集合,有两种操作:1.合并集合中的两个元素,新元素为两个元素之和 2.分裂集合中的一个元素,得到的两个新元素之和等于原先的元素.要求用最小步数使初始集合变为目标集合, ...
- 【状压dp】Bzoj2064 分裂
Description 背景: 和久必分,分久必和... 题目描述: 中国历史上上分分和和次数非常多..通读中国历史的WJMZBMR表示毫无压力. 同时经常搞OI的他把这个变成了一个数学模型. 假设中 ...
- 2018.10.24 bzoj2064: 分裂(状压dp)
传送门 状压dp好题. 考虑对于两个给出的集合. 如果没有两个元素和相等的子集,那么只能全部拼起来之后再拆开,一共需要n1+n2−2n1+n2-2n1+n2−2. 如果有呢? 那么对于没有的就是子问题 ...
- 分裂 BZOJ2064 状压DP
分析: 这个题很好啊,比起什么裸的状压DP高多了! 我们可以考虑,什么时候答案最大:全合并,之后再分裂 这样,我们必定可以得到答案,也就是说答案必定小于n+m 那么我们可以考虑,什么时候能够使答案更小 ...
- bzoj2064: 分裂(状压dp)
Description 背景: 和久必分,分久必和... 题目描述: 中国历史上上分分和和次数非常多..通读中国历史的WJMZBMR表示毫无压力. 同时经常搞OI的他把这个变成了一个数学模型. 假设中 ...
- [BZOJ2064]分裂 状压dp
2064: 分裂 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 656 Solved: 404[Submit][Status][Discuss] De ...
- UVa 11825 集合dp
#include <cstdio> #include <cstring> #include <iostream> #include <cmath> #i ...
- BZOJ2064: 分裂
2064: 分裂 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 360 Solved: 220[Submit][Status][Discuss] De ...
- UVALive 7721 K - 2-ME Set 集合dp,所有数的位或来表示状态。
/** 题目:UVALive 7721 K - 2-ME Set 链接:https://vjudge.net/problem/UVALive-7721 题意:给定n个数,从中取出一个集合,至少包含两个 ...
随机推荐
- hdu2509Be the Winner(反nim博弈)
Be the Winner Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- linux基础——文件挂载,lamp安装
一. 文件挂载 lsblk -f 显示文件系统信息 mount -t vfat UUID="ffffffffff" /mnt 挂载到/mnt目录 Linux针对于各式U盘挂载方 ...
- 应用UserDefaults储存游戏分数和最高分
应用UserDefaults储存游戏分数和最高分 我们在GameScene.swift里 private var currentScore:SKLabelNode! // 当前分数节点 private ...
- 397. Longest Continuous Increasing Subsequence
Description Give an integer array,find the longest increasing continuous subsequence in this array. ...
- (python)leetcode刷题笔记 01 TWO SUM
1. Two Sum Given an array of integers, return indices of the two numbers such that they add up to a ...
- HADOOP/HDFS Essay
HDFS架构 the core of HADOOP/distributed systems is storeage(HDFS) and resource manager(YARN) for compu ...
- opencv-学习笔记(3)
opencv-学习笔记(3) 这章讲了 图像加法 opencv测试效率 IPYTHON测试效率 图像加法 cv2.add() 要求,两图片必须大小类型相同 然后是图像混合cv2.addWeighted ...
- Docker: 如何修改 Docker 的镜像存储位置
我用的阿里云的服务器, 但是系统盘只有20G, 默认 Docker 的镜像文件是安装在/var/lib 目录下的, 这样的话我根本装不了太多的镜像... 这个必须得改改... 搜了下, 解决方案如下: ...
- $http.get(...).success is not a function 错误解决
$http.get(...).success is not a function 错误解决 1.6 新版本的AngularJs中用then和catch 代替了success和error,用PRomis ...
- win7 个人电脑 IIS7服务器(web服务器) 同一局域网下均可访问本机网页
建立web服务器: 1.控制面板-->程序-->打开或关闭windows功能-->internet信息服务全部打钩,确定即可. 访问网页: 1.C:\inetpub\wwwroot\ ...