P4574 [CQOI2013]二进制A+B
传送门
思路:
本题可用数位DP来做,设 f [ i ][ a ][ b ][ c ][ j ] 表示当前枚举到(二进制下的)第i位,a' b' c'各用a,b,c了几个1,j表示最后一位是否有进位。转移方程就只要暴力枚举8种情况(不同位置及是否进位)。
DP方程:
inline void dp()//动态规划,强行枚举八种情况
{
f[][][][][]=;
for (int i=;i<n;++i)
for (int j=;j<=jla;++j)
for (int k=;k<=jlb;++k)
for (int l=;l<=jlc;++l)
{
long long tmp=f[i][j][k][l][];//枚举最后一位不进位的情况
f[i+][j+][k+][l+][]=min(f[i+][j+][k+][l+][],tmp+(<<i+));
f[i+][j+][k][l+][]=min(f[i+][j+][k][l+][],tmp+(<<i));
f[i+][j][k+][l+][]=min(f[i+][j][k+][l+][],tmp+(<<i));
f[i+][j][k][l][]=min(f[i+][j][k][l][],tmp);
tmp=f[i][j][k][l][];//枚举最后一位进位的情况
f[i+][j+][k+][l+][]=min(f[i+][j+][k+][l+][],tmp+(<<i+));
f[i+][j][k+][l][]=min(f[i+][j][k+][l][],tmp+(<<i));
f[i+][j+][k][l][]=min(f[i+][j+][k][l][],tmp+(<<i));
f[i+][j][k][l][]=min(f[i+][j][k][l][],tmp);
}
}
由上DP转移方程可看出,如果是枚举最后一位进位的情况,则需要转移到不进位的DP方程。因为二进制是逢二进一,最后一位如果为1,且进位,就要变为0;如果是从不进位开始转移,则与进位相反。
完整代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define INF 0x7f7f7f7f7f7f7f
int T,a,b,c;
int n,jla,jlb,jlc;//n记录三个数的二进制数码长度的最大值,jla、jlb、jlc分别记录a、b、c的二进制数码中 1 的个数
long long f[][][][][];
inline int read()//快读
{
char kr=;
char ls;
for(;ls>''||ls<'';kr=ls,ls=getchar());
int xs=;
for(;ls>=''&&ls<='';ls=getchar())
{
xs=xs*+ls-;
}
if(kr=='-') xs=-xs;
return xs;
}
inline int lowbit(int x)//求出x的二进制数码中 1 的个数
{
int sum=;
for (;x;x>>=)
sum+=x&;
return sum;
}
inline void dp()//动态规划,强行枚举八种情况
{
f[][][][][]=;
for (int i=;i<n;++i)
for (int j=;j<=jla;++j)
for (int k=;k<=jlb;++k)
for (int l=;l<=jlc;++l)
{
long long tmp=f[i][j][k][l][];//枚举最后一位不进位的情况
f[i+][j+][k+][l+][]=min(f[i+][j+][k+][l+][],tmp+(<<i+));
f[i+][j+][k][l+][]=min(f[i+][j+][k][l+][],tmp+(<<i));
f[i+][j][k+][l+][]=min(f[i+][j][k+][l+][],tmp+(<<i));
f[i+][j][k][l][]=min(f[i+][j][k][l][],tmp);
tmp=f[i][j][k][l][];//枚举最后一位进位的情况
f[i+][j+][k+][l+][]=min(f[i+][j+][k+][l+][],tmp+(<<i+));
f[i+][j][k+][l][]=min(f[i+][j][k+][l][],tmp+(<<i));
f[i+][j+][k][l][]=min(f[i+][j+][k][l][],tmp+(<<i));
f[i+][j][k][l][]=min(f[i+][j][k][l][],tmp);
}
}
inline void clear()//为做DP初始化
{
memset(f,INF,sizeof(f));
n=max((int)log2(a)+,(int)log2(b)+);
n=max(n,(int)log2(c)+);//求 n
jla=lowbit(a),jlb=lowbit(b),jlc=lowbit(c);
}
int main()
{
a=read();b=read();c=read();
clear();
dp();
if(f[n][jla][jlb][jlc][]>=INF)//注意是“≥INF”
{
printf("-1\n");
return ;
}//如果无解就输出-1
printf("%lld\n",f[n][jla][jlb][jlc][]);//输出最小值
return ;
}
一些注意事项:
①本题的 f 数组要开long long 不然会爆。
②INF也要尽量开大。
②在判断无解时要判 " ≥ INF ”(因为转移过程中会加上部分的值)
其他的一些细节瞎搞搞就AC了。
P4574 [CQOI2013]二进制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 ...
- BZOJ3107 CQOI2013二进制A+B(动态规划)
显然答案只与a.b.c中各自1的个数及位数有关.a.b只考虑前i位怎么填时,c最多在第i+1位上为1,而第i+1位及之后的a.b怎么填都不会对前i位造成影响.于是设f[n][i][j][k][0/1] ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- 使用struct处理二进制
有的时候需要用python处理二进制数据,比如,存取文件.socket操作时.这时候,可以使用python的struct模块来完成. struct模块中最重要的三个函数是pack(), unpack( ...
- 如何开启MySQL 5.7.12 的二进制日志
1. 打开/etc下的my.cnf文件 2. 编辑它,添加内容: log_bin=binary-log #二进制日志的文件名 server_id=1 #必须指定server_id,这是MySQL ...
- 【.net 深呼吸】使用二进制格式来压缩XML文档
在相当多的情况下,咱们写入XML文件默认是使用文本格式来写入的,如果XML内容是通过网络传输,或者希望节省空间,特别是对于XML文档较大的情况,是得考虑尽可能地压缩XML文件的大小. XmlDicti ...
- Javascript的二进制数据处理学习 ——nodejs环境和浏览器环境分别分析
以前用JavaScript主要是处理常规的数字.字符串.数组对象等数据,基本没有试过用JavaScript处理二进制数据块,最近的项目中涉及到这方面的东西,就花一段时间学了下这方面的API,在此总结一 ...
- 浅析MySQL基于ROW格式的二进制日志
上文分析的二进制日志实际上是基于STATEMENT格式的,下面我们来看看基于ROW格式的二进制日志,毕竟,两者对应的binlog事件类型也不一样,同时,很多童鞋反映基于ROW格式的二进制日志无法查到原 ...
- 浅析MySQL二进制日志
查看MySQL二进制文件中的内容有两种方式 1. mysqlbinlog 2. SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offs ...
随机推荐
- CentOS下shell显示-bash-4.1$不显示用户名路径
Linux CentOS下shell显示-bash-4.1$不显示用户名路径的解决方法. 问题描述: CentOS下新增一个用户,登录进去之后shell脚本的信息如下: -bash-4.1$ \ -b ...
- kivy中size和pos的使用
kivy中位置和大小属性的使用: -------------------位置---------------------------- 1.pos_hint(‘x-axis-key’:value,’y- ...
- Linux查看机器和硬盘的SN
查看硬件RAID中某块硬盘SN # sas 口: [root@ ~]$ smartctl -a /dev/sda -d megaraid,n *** Serial number: 6RJ974SR * ...
- HELLO JAVA!
从今天开始,我将不定期地更新自己在大学学习到的JAVA知识,欢迎大家一同前来观摩学习,如有纰漏还请多多赐教2018-09-1715:39:14
- 04: vue生命周期和实例属性和方法
1.4 组件的生命周期 1.说明 1. Vue将组件看成是一个有生命的个体,跟人一样,定义了各个阶段, 2. 组件的生命周期:组件的创建过程 3. 组件生命周期钩子函数:当组件处在某个阶段,要执行某个 ...
- 线程同步——用户模式下线程同步——Interlocked实现线程同步
线程同步分为用户模式下的线程同步和内核对象的线程同步. 当然用户模式下的线程同步实现速度比内核模式下快,但是功能也有局 //1.利用原子访问: Interlocked系列函数,关于Interlocke ...
- Iterator和Iterable的区别以及使用
Iterator和Iterable的区别以及使用 1.什么是迭代器 迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址.迭代 ...
- tf.nn.max_pool
tf.nn.max_pool(value, ksize, strides, padding, name=None) 参数是四个,和卷积很类似: Args Annotation 第一个参数value ...
- Codeforces Round #425 (Div. 2) Problem A Sasha and Sticks (Codeforces 832A)
It's one more school day now. Sasha doesn't like classes and is always bored at them. So, each day h ...
- django基础 -- 3. urls.py view.py 参数 别名 重定向 常用方法 静态文件
一.基本格式 from django.conf.urls import url from . import views #循环urlpatterns,找到对应的函数执行,匹配上一个路径就找到对应的函数 ...