【题解】P6218 [USACO06NOV] Round Numbers S
这是一道数位DP。
令 \(dp_{i,j,k}\) 为满足由 \(i\) 位组成,且其中有 \(j\) 个1,第 i 位(从右往左数)为 \(k\) 的二进制数的数量。
可以得出状态转移方程:
\(dp_{i,j,0}=dp_{i-1,j,1}+dp_{i-1,j,0}\;(2\le i,0\le j< i)\)
\(dp_{i,j,1}=dp_{i-1,j-1,0}+dp_{i-1,j-1,1}\;(2\le i,0<j\le i)\)
边界:\(dp_{1,0,0}=1,dp_{1,1,1}=1\)
对于 \(dp_{i,j,k}\),如果满足 \(1\le i,0\le j\le \lfloor \frac{i}{2}\rfloor\),则这个状态是合法的。因为0的个数为 \(i-j\),要满足 \(j\le i-j\),则 \(2j\le i\) 所以 \(j\le \lfloor \frac{i}{2}\rfloor\)
令 \(f(x)\) 为区间 \([1,x-1]\) 内的“圆数”个数,则区间 \([L,R]\) 内的“圆数”个数为 \(f(R+1)-f(L)\)。
对于求\(f(x)\),我们先将 \(x\) 转换成二进制,设其二进制位数为 \(len\)。
将二进制位数小于 \(len\) 的“圆数”个数统计到答案中。这时,对于 \(dp_{i,j,k}\),如果满足 \(1\le i,0\le j\le \lfloor \frac{i}{2}\rfloor\),则这个状态是合法的。因为0的个数为 \(i-j\),要满足 \(j\le i-j\),则 \(2j\le i\) 所以 \(j\le \lfloor \frac{i}{2}\rfloor\)
对于 \(x\) 的二进制除首位外的每一位 \(i\),都判断其是否为1 。如果为1,说明存在一些数,它们长度为 \(len\),值小于 \(x\),且二进制表示中的前 \(i-1\) 位与 \(x\) 相同,第 \(i\) 位为0 。然后将这些数中的“圆数”个数加入答案即可。这时,判断一个状态是否合法,需要考虑前 \(i-1\)位中0和1的个数。
参考代码
略微压行,轻喷。
#include <cstdio>
#include <cstring>
using namespace std;
#define in __inline__
typedef long long ll;
#define rei register int
#define FOR(i, l, r) for(rei i = l; i <= r; ++i)
#define FOL(i, r, l) for(rei i = r; i >= l; --i)
char inputbuf[1 << 23], *p1 = inputbuf, *p2 = inputbuf;
#define getchar() (p1 == p2 && (p2 = (p1 = inputbuf) + fread(inputbuf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
in int read() {
int res = 0; char ch = getchar(); bool f = true;
for(; ch < '0' || ch > '9'; ch = getchar())
if(ch == '-') f = false;
for(; ch >= '0' && ch <= '9'; ch = getchar())
res = res * 10 + (ch ^ 48);
return f ? res : -res;
}
const int N = 40;
ll dp[N][N][2];
int a, b, A[N], la, lb, B[N];
ll solve(int x[], int len) {
ll res = 0; int s0 = 0, s1 = 1;
//s0表示0的个数,s1表示1的个数
FOL(i, len - 1, 1) FOR(j, 0, (i >> 1)) res += dp[i][j][1];//第1类数
FOL(i, len - 1, 1) {//第二类数
if(x[i]) FOR(j, 0, i) if(s0 + i - j >= s1 + j) res += dp[i][j][0];
//s0+i-j表首位至当前位0的个数,s1+j表首位至当前位1的个数,注意j要枚举至i
x[i] ? (++s1) : (++s0);
}
return res;
}
signed main() {
a = read(), b = read();
for(; a; a >>= 1) A[++la] = a & 1;
for(; b; b >>= 1) B[++lb] = b & 1;//转换成二进制
++B[1];
for(rei i = 2; i <= lb && B[i - 1] == 2; ++i) B[i - 1] = 0, ++B[i];
if(B[lb] == 2) B[lb] = 0, B[++lb] = 1;
while(!A[la]) --la;
while(!B[lb]) --lb;//给B加上1
dp[1][0][0] = dp[1][1][1] = 1;
FOR(i, 2, lb) FOR(j, 0, i) {//DP
if(j < i) dp[i][j][0] = dp[i - 1][j][1] + dp[i - 1][j][0];
if(j) dp[i][j][1] = dp[i - 1][j - 1][0] + dp[i - 1][j - 1][1];
}
printf("%lld\n", solve(B, lb) - solve(A, la));
return 0;//结束
}
【题解】P6218 [USACO06NOV] Round Numbers S的更多相关文章
- 洛谷 P6218 [USACO06NOV] Round Numbers S
洛谷 P6218 [USACO06NOV] Round Numbers S 题目描述 如果一个正整数的二进制表示中,\(0\) 的数目不小于 \(1\) 的数目,那么它就被称为「圆数」. 例如,\(9 ...
- POJ 3252 Round Numbers 数学题解
Description The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, P ...
- 题解【POJ3252】Round Numbers
Description The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, P ...
- 【BZOJ1662】[Usaco2006 Nov]Round Numbers 圆环数 数位DP
[BZOJ1662][Usaco2006 Nov]Round Numbers 圆环数 Description 正如你所知,奶牛们没有手指以至于不能玩"石头剪刀布"来任意地决定例如谁 ...
- [BZOJ1662][POJ3252]Round Numbers
[POJ3252]Round Numbers 试题描述 The cows, as you know, have no fingers or thumbs and thus are unable to ...
- Round Numbers(组合数学)
Round Numbers Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10484 Accepted: 3831 Descri ...
- bzoj1662: [Usaco2006 Nov]Round Numbers 圆环数
Description 正如你所知,奶牛们没有手指以至于不能玩“石头剪刀布”来任意地决定例如谁先挤奶的顺序.她们甚至也不能通过仍硬币的方式. 所以她们通过"round number" ...
- BZOJ1662: [Usaco2006 Nov]Round Numbers
1662: [Usaco2006 Nov]Round Numbers Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 147 Solved: 84[Sub ...
- 【BZOJ】1662: [Usaco2006 Nov]Round Numbers 圆环数(数位dp)
http://www.lydsy.com/JudgeOnline/problem.php?id=1662 这道题折腾了我两天啊-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 果然 ...
随机推荐
- Jmeter简单压测之服务器监控
此篇为最近工作需要到内容,故现在做一个总结. 最近家里电脑坏了,等待会公司空闲在编写. 文章构思中,敬请期待.......
- 集训模拟赛-1-T2
好了不要在铺垫了直接整吧就 题目拿来!!!!!!! 倒水 (water) (256MB,1s) [问题描述] 你有一个水桶(记为 0),两个杯子(记为 1,2).水桶中的水量无限,容量也无限.1 号杯 ...
- tomcat 在linux下启动时找不到JDK
方案一. 修改bashrc (转载: https://www.cnblogs.com/hongzg1982/articles/2101792.html) $ vim ~/.bashrc #加入JA ...
- js循环数组方法some和forEach怎么用
forEach不支持break和return.一般普通循环都是用forEach ar arr1=["aa","bb","aa"," ...
- git&&SourceTree使用总结
git&&sourceTree操作学习 基本操作 commit 提交 pull 更新代码 push 推送代码 fetch 抓取代码 Branch 新建分支 merge 合并代码 Sta ...
- python gdal 写GeoTiff文件
1.gdal数据类型 (1)GDT_Byte(int8) (2)GDT_UInt16 (3)GDT_Int16 (4)GDT_UInt32 (5)GDT_Int32 (6)GDT_Float3 ...
- 【Hadoop离线基础总结】Hadoop的架构模型
Hadoop的架构模型 1.x的版本架构模型介绍 架构图 HDFS分布式文件存储系统(典型的主从架构) NameNode:集群当中的主节点,主要用于维护集群当中的元数据信息,以及接受用户的请求,处理用 ...
- 微服务框架 ketchup 介绍
1.背景 在ketchup诞生之前.期间也是用surging开发了两个项目.奈何surging没有文档,升级之后,只能从头在读一遍源码,了解新功能,会消耗大量的时间.商业化也使一些 想学习微服务的人望 ...
- vue组件试错
[Vue warn]: Property or method "child1" is not defined on the instance but referenced duri ...
- 重学 Java 设计模式:实战工厂方法模式
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获!