[bzoj3107][CQOI2013]二进制a+b
来源:互联网 发布:medea软件 编辑:程序博客网 时间:2024/06/05 14:34
题目大意及模型转换
给定三个二进制数a,b,c。对每个数进行重组变为a’,b’,c’。你需要满足a’+b’=c’,并令c’最小。若无解输出-1。
a,b,c<=
考虑简化
其实,我们发现有用的东西只是a,b,c的最大位数(决定了答案最多可以多少位,注意这里的位数是十进制下的,那么最小的答案都超过极限位数证明输出-1),以及a,b,c中1的个数(记为x,y,z)。为方便讨论,我们应当规定x>=y。
分类讨论
现在我们考虑这样一个子问题。
设为
z=1
很显然了,举个例子x=10,y=5,z=1。
当p=0时:
最优策略是把x个1都堆在后面,最低位放1,然后接下来再放y-1个1,使得c’最高位为1。
所以
当p=1时:
最优策略是把x个1都堆在后面,但因为有进位,所以最低位不能放1,然后再往前放y个1,同样令c’最高位为1。
所以
所以
z=y
设x=10,y=5,z=5。
当p=0时:
显然这种情况保证a’,b’最小会最优。因为a’,b’最小时刚好c’有y个1,所以合法。又因为a’,b’最小,所以c’也最小。
所以
当p=1时:
这种情况我们只能把b’最低位变成0,然后在第x+1位补上一个1,使得c’的最高位的1落在第x+2位。
所以
所以
1<z<y
假设x=10,y=5,z=3。
有点不好搞。我们来看看最低位应该怎么弄,然后可以继续将它分成下一个子问题。先考虑p=0。
如果最低位是1+0=1,那么下一个子问题将会变为
按照策略会继续减,一直到z=1时。
那么答案自然是
如果最低位是0+1=1,那么下一个子问题将会变为
按照策略已知道z=1。
那么答案自然是
两种一样,我们合并。
如果最低位是1+1=0,那么下一个子问题将会变为
按照策略会一直到y=z时。
那么答案自然是
我们进行比较。
第一、二种策略:
第三种策略:
由于我们知道y>z。那么显然第三种策略更优。
p=1可以研究一下,还是1+1最优。
因此可以得知。
y<z<=x
x=10,y=5,z=8,p=0。
这种情况不需要管进位。
因为初始状态p=0,而这种情况只有初始情况才会出现。
在c’中如果它的1跑的比较后面,它就会比较小。
因此最后z-y位都应该是1+0=1。
直至缩到y=z。
所以
x<z<=x+y
x=10,y=5,z=12,p=0。
这种情况同样不需要理进位。
同样我们使c’的1弄到后面去。
因此最后z-x位都应该是0+1=1。
所以
z=x+y
不需要理进位。
x=10,y=5,z=15,p=0。
显然可得。
不是以上情况中任意一种
solve(x,y,z,p)=-1
注意
最终得到的答案应该和最大位比较。
参考代码
(写的很优美呢)
#include<cstdio>#include<algorithm>#include<cmath>#define fo(i,a,b) for(i=a;i<=b;i++)#define two(x) (1<<x)using namespace std;int i,j,k,l,t,n,m,ans,a,b,c,x,y,z;int lowbit(int x){ return x&-x;}int getone(int x){ int y=0; while (x){ y++; x-=lowbit(x); } return y;}int getws(int x){ int y=0; while (x){ y++; x/=2; } return y;}int solve(int x,int y,int z,int p){ if (z==1) return two(x+y+p-1); else if (z>1&&z<y) return 2*solve(x-1,y-1,z-p,1)+p; else if (z==y) return two(x+p)+two(y-p)-2+p; else if (z>y&&z<=x) return two(z-y)*solve(x+y-z,y,y,0)+two(z-y)-1; else if (z>x&&z<x+y) return two(z-x)*solve(x,y+x-z,x,0)+two(z-x)-1; else if (z==x+y) return two(z)-1; else return -1;}int main(){ scanf("%d%d%d",&a,&b,&c); x=getone(a);y=getone(b);z=getone(c); n=max(max(getws(a),getws(b)),getws(c)); if (x<y) swap(x,y); ans=solve(x,y,z,0); if (getws(ans)>n) ans=-1; printf("%d\n",ans);}
- [bzoj3107][CQOI2013]二进制a+b
- BZOJ3107: [cqoi2013]二进制a+b
- 【BZOJ3107】【cqoi2013】二进制a+b
- bzoj3107: [cqoi2013]二进制a+b DP
- [BZOJ3107][CQOI2013]二进制a+b(DP)
- 【BZOJ3107】二进制a+b,DP
- [CQOI2013]二进制a+b
- BZOJ 3107 CQOI2013 二进制a+b 构造
- bzoj 3107: [cqoi2013]二进制a+b 构造
- 【CQOI2013】二进制a+b 动态规划
- [二进制构造 || DP] BZOJ 3107 [cqoi2013]二进制a+b
- BZOJ 3107 [cqoi2013]二进制a+b 分类讨论
- bzoj 3107: [cqoi2013]二进制a+b 数位dp
- SGU 112 a^b - b^a 大数+二进制优化
- A+B的和的二进制
- 【BZOJ 3107】【CQOI 2013】二进制a+b
- 二进制数a,b有多少位不同.
- 哈理工 2084 A+B(二进制加法)
- OpenSSL(加密方式,加密算法,自签证书)
- Struts(12)MySQL数据库访问
- 转载点关于lunix的命令
- zzuli OJ 1000: 整数a+b
- HDU 1301 Jungle Roads
- [bzoj3107][CQOI2013]二进制a+b
- 常用数据库对比
- pow(x,n)
- MyBatis教程之分页和动态SQL语句基础
- 面试进行曲之技术面试(项目经验)
- Struts(11)文件上传
- IIS 服务器的配置
- 获取键盘高度
- Eclipse使用入门教程