BZOJ 3107 二进制a+b
Description
输入三个整数\(a, b, c\),把它们写成无前导\(0\)的二进制整数。比如\(a=7, b=6, c=9\),写成二进制为\(a=111, b=110, c=1001\)。接下来以位数最多的为基准,其他整数在前面添加前导\(0\),使得\(a, b, c\)拥有相同的位数。比如在刚才的例子中,添加完前导\(0\)后为\(a=0111, b=0110, c=1001\)。最后,把\(a, b, c\)的各位进行重排,得到\(a’, b’, c’\),使得\(a’+b’=c’\)。比如在刚才的例子中,可以这样重排:\(a’=0111, b’=0011, c’=1010\)。
你的任务是让\(c’\)最小。如果无解,输出\(-1\)。
Input
输入仅一行,包含三个整数\(a, b, c\)。
Output
输出仅一行,为\(c’\)的最小值。
Sample Input
7 6 9
Sample Output
10
HINT
\(a,b,c \le 2^{30}\)
自己难得看出来一道高维的\(dp\)题目:\(f[i][j][k][l][m]\)表示前\(i\)位二进制数中,\(a’\)用了\(j\)个1,\(b’\)用了\(k\)个\(1\),合成的\(c’\)在前\(i\)位中有\(l\)个\(1\)。
于是,根据二进制加法,我们可以得到\(dp\)方程:
\]
\]
\]
\]
\]
\]
\]
\]
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
using namespace std;
typedef long long ll;
#define maxn (35)
ll a,b,c,f[maxn][maxn][maxn][maxn][2];
int n,w1,w2,w3;
inline void ready()
{
memset(f,0x7,sizeof(f));
f[0][0][0][0][0] = 0;
int cnt,i;
for (i = a,cnt = 0;i;i >>= 1,++cnt) if (i & 1) ++w1;
n = max(n,cnt);
for (i = b,cnt = 0;i;i >>= 1,++cnt) if (i & 1) ++w2;
n = max(n,cnt);
for (i = c,cnt = 0;i;i >>= 1,++cnt) if (i & 1) ++w3;
n = max(n,cnt);
}
inline void dp()
{
for (int i = 0;i < n;++i)
for (int j = 0;j <= i&&j <= w1;++j)
for (int k = 0;k <= i&&k <= w2;++k)
for (int l = 0;l <= i&&l <= w3;++l)
{
if (j < w1)
{
if (l < w3) f[i+1][j+1][k][l+1][0] = min(f[i+1][j+1][k][l+1][0],f[i][j][k][l][0]|(1<<i));
f[i+1][j+1][k][l][1] = min(f[i+1][j+1][k][l][1],f[i][j][k][l][1]);
}
if (k < w2)
{
if (l < w3) f[i+1][j][k+1][l+1][0] = min(f[i+1][j][k+1][l+1][0],f[i][j][k][l][0]|(1<<i));
f[i+1][j][k+1][l][1] = min(f[i+1][j][k+1][l][1],f[i][j][k][l][1]);
}
if (j < w1&&k < w2)
{
f[i+1][j+1][k+1][l][1] = min(f[i+1][j+1][k+1][l][1],f[i][j][k][l][0]);
if (l < w3) f[i+1][j+1][k+1][l+1][1] = min(f[i+1][j+1][k+1][l+1][1],f[i][j][k][l][1]|(1<<i));
}
if (l < w3) f[i+1][j][k][l+1][0] = min(f[i+1][j][k][l+1][0],f[i][j][k][l][1]|(1<<i));
f[i+1][j][k][l][0] = min(f[i+1][j][k][l][0],f[i][j][k][l][0]);
}
}
int main()
{
freopen("3107.in","r",stdin);
freopen("3107.out","w",stdout);
scanf("%lld %lld %lld",&a,&b,&c);
ready();
dp();
if (f[n][w1][w2][w3][0] > (1ll<<40)) printf("-1");
else printf("%lld",f[n][w1][w2][w3][0]);
fclose(stdin); fclose(stdout);
return 0;
}
BZOJ 3107 二进制a+b的更多相关文章
- BZOJ 3107 [cqoi2013]二进制a+b (DP)
3107: [cqoi2013]二进制a+b Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 995 Solved: 444[Submit][Stat ...
- bzoj 1192 二进制
原题传送门http://www.lydsy.com/JudgeOnline/problem.php?id=1192 继续刷水题,二进制思想 //By BLADEVIL var x :longint; ...
- BZOJ 1531 二进制优化多重背包
思路: 讲道理我应该写单调队列优化多重背包的 但是我不会啊 但是我现在! 还不会啊 我就写了个二进制优化的.. 过了 //By SiriusRen #include <cstdio> #i ...
- BZOJ.3425.[POI2013]Polarization(DP 多重背包 二进制优化)
BZOJ 洛谷 最小可到达点对数自然是把一条路径上的边不断反向,也就是黑白染色后都由黑点指向白点.这样答案就是\(n-1\). 最大可到达点对数,容易想到找一个点\(a\),然后将其子树分为两部分\( ...
- [BZOJ 2989]数列(二进制分组+主席树)
[BZOJ 2989]数列(二进制分组+主席树) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[ ...
- 题解 bzoj 4398福慧双修(二进制分组)
二进制分组,算个小技巧 bzoj 4398福慧双修 给一张图,同一条边不同方向权值不同,一条边只能走一次,求从1号点出发再回到1号点的最短路 一开始没注意一条边只能走一次这个限制,打了个从一号点相邻节 ...
- [Bzoj 1192][HNOI2006]鬼谷子的钱袋(二进制优化多重背包)
(人生第一篇bzoj题解有点激动 首先介绍一下题目: 看它题目那么长,其实意思就是给定一个数a,求将其拆分成n个数,通过这n个数可以表示出1~a中所有数的方案中,求最小的n. 您看懂了嘛?不懂咱来举个 ...
- [BZOJ 2165] 大楼 【DP + 倍增 + 二进制】
题目链接:BZOJ - 2165 题目分析: 这道题我读了题之后就想不出来怎么做,题解也找不到,于是就请教了黄学长,黄学长立刻秒掉了这道题,然后我再看他的题解才写出来..Orz 使用 DP + 倍增 ...
- BZOJ 1192 鬼谷子的钱袋 (二进制思想)
题解:鉴于二进制的思想来划分 #include <cstdio> int main(){ int n,d=0;scanf("%d",&n); while(1&l ...
随机推荐
- Android RecyclerView使用(一)
RecyclerView一种可以替换掉listview gridview 瀑布流等控件的新视图控件,控制视图回收和复用 ==优化内存可以替换listview 与listview的不同之处是:listv ...
- Hadoop最基本的wordcount(统计词频)
package com.uniclick.dapa.dstest; import java.io.IOException; import java.net.URI; import org.apache ...
- Hadoop流程---从tpch到hive
刚接触Hadoop,看了一周的Hadoop及其相应的组件,感觉效果不是很明显,于是将找个例子练一下手,跑一个流程,加深对hadoop的理解. 设计的流程如下: TPC_H--->HdFS---- ...
- Markdown写接口文档,自动添加TOC
上回说到,用Impress.js代替PPT来做项目展示.这回换Markdown来做接口文档好了.(不敢说代替Word,只能说个人感觉更为方便)当然,还要辅之以Git,来方便版本管理. Markdown ...
- Python:构建缓冲带提取区域平均坡度
前一段时间做提取坡度的问题,当时首先想到的是使用ArcEngine来做,因为记得有ITopoOperator接口可以构建缓冲带,用IExtractionRaster可以掩膜栅格数据,利用IPixelB ...
- 快速记忆JavaScript中exec和match的使用
JS模式匹配中exec,match用得非常多,所以掌握其用法对我们进行字符串的处理帮助非常大 1.exec的定义其用法 exec与match主要的不同是,exec是正则表达式里面的方法. ...
- 【原创】Git版本控制器的基本使用
关于git Git,是一个分布式版本控制软件.最初本是为了更好的管理Linux内核开发而被林纳斯·托瓦兹开发,后来因为项目开发中版本控制的强烈需求,而git也日趋成熟,最终成为了一个独立的版本控制软件 ...
- jQuery 效果 - 滑动
jQuery 滑动方法可使元素上下滑动. 点击这里,隐藏/显示面板 实例 jQuery slideDown()演示 jQuery slideDown() 方法. jQuery slideUp()演示 ...
- TCP/UDP基本概念部分
最近在读<Unix网络编程>和<TCP/IP详解>两本书,有了一些自己的心得与体会,总结下其中典型的问题. 1. 为什么建立连接需要三次握手? 谢希仁的<计算机网络> ...
- asp.net 网站和asp.net Web 应用程序的一处不同
环境为:VS2008Team+.net3.5 asp.net 网站前台页面<%= %>这样绑定可以,asp.net Web 应用程序就不可以 示例代码如下: 1.asp.net网站 < ...