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 ...
随机推荐
- bzoj3678 简单题
题目链接 bitset #include<algorithm> #include<iostream> #include<cstdlib> #include<c ...
- 课堂测试代码(未完全实现,部分代码有bug,仅供参考)
//信1705-3 20173507 周龙海package account; public class account { private String accountID; private Stri ...
- Docker学习笔记之常见 Dockerfile 使用技巧
0x00 概述 在掌握 Dockerfile 的基本使用方法后,我们再来了解一些在开发中使用 Dockerfile 的技巧.这一小节的展现方式与之前的略有不同,其主要来自阅读收集和我自身在使用中的最佳 ...
- K8S学习笔记之CentOS7集群使用Chrony实现时间同步
0x00 概述 容器集群对时间同步要求高,实际使用环境中必须确保集群中所有系统时间保持一致,openstack官方也推荐使用chrony代替ntp做时间同步. Chrony是一个开源的自由软件,像Ce ...
- mariadb的flashback到底怎么样???防误删可以,但算不上真正的闪回--再看mariadb 10.3的System-Versioned Tables
mariadb 在10.2.4引入闪回特性,支持DML(INSERT, DELETE, UPDATE)操作的闪回,不支持DDL语句,使用闪回,必须设置binlog_row_image=FULL. 其原 ...
- 关于PRD、MRD、BRD文档
笔者现在所在的公司有专职的产品经理,在职业生涯最长的那家公司,并没有专门的产品经理,虽然在创业公司期间有产品经理,但是似乎产品经理更多的是和客户沟通需求,反馈,并不输出正规意义上产品经理该有的输出.从 ...
- 一致性哈希算法(适用于分库分表、RPC负载均衡)转
在分布式应用中,应该来说使用到hash最多的地方就是rpc负载均衡和分库分表,通常对于正式意义上的分布式应用来说,扩容和收缩是一个半自动化的过程,在此期间,应用基本上是可用的,所以不能发生大规模动荡的 ...
- Matlab绘制三维曲面(以二维高斯函数为例)
原文地址为:Matlab绘制三维曲面(以二维高斯函数为例) 寒假学习了一下Python下的NumPy和pymatlab,感觉不是很容易上手.来学校之后,决定继续看完数字图像处理一书.还是想按照上学期的 ...
- 浅谈k短路算法
An Old but Classic Problem 给定一个$n$个点,$m$条边的带正权有向图.给定$s$和$t$,询问$s$到$t$的所有权和为正路径中,第$k$短的长度. Notice 定义两 ...
- linux --- 3 vim 网络 用户 权限 软连接 压缩 定时任务 yum源
一.vi 和vim vi 是老式的字处理器,不过功能已经很齐全了,但是还是有可以进步的地方. vim 则可以说是程序开发者的一项很好用的工具 ①命令模式 移动光标 w(e) 移动光标到下一个单词 b ...