题目传送门

这是一道数位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\)。

  1. 将二进制位数小于 \(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\)

  2. 对于 \(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的更多相关文章

  1. 洛谷 P6218 [USACO06NOV] Round Numbers S

    洛谷 P6218 [USACO06NOV] Round Numbers S 题目描述 如果一个正整数的二进制表示中,\(0\) 的数目不小于 \(1\) 的数目,那么它就被称为「圆数」. 例如,\(9 ...

  2. POJ 3252 Round Numbers 数学题解

    Description The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, P ...

  3. 题解【POJ3252】Round Numbers

    Description The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, P ...

  4. 【BZOJ1662】[Usaco2006 Nov]Round Numbers 圆环数 数位DP

    [BZOJ1662][Usaco2006 Nov]Round Numbers 圆环数 Description 正如你所知,奶牛们没有手指以至于不能玩"石头剪刀布"来任意地决定例如谁 ...

  5. [BZOJ1662][POJ3252]Round Numbers

    [POJ3252]Round Numbers 试题描述 The cows, as you know, have no fingers or thumbs and thus are unable to ...

  6. Round Numbers(组合数学)

    Round Numbers Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10484 Accepted: 3831 Descri ...

  7. bzoj1662: [Usaco2006 Nov]Round Numbers 圆环数

    Description 正如你所知,奶牛们没有手指以至于不能玩“石头剪刀布”来任意地决定例如谁先挤奶的顺序.她们甚至也不能通过仍硬币的方式. 所以她们通过"round number" ...

  8. BZOJ1662: [Usaco2006 Nov]Round Numbers

    1662: [Usaco2006 Nov]Round Numbers Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 147  Solved: 84[Sub ...

  9. 【BZOJ】1662: [Usaco2006 Nov]Round Numbers 圆环数(数位dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1662 这道题折腾了我两天啊-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 果然 ...

随机推荐

  1. go 模板详说

    模板是我们常用的手段用于动态生成页面,或者用于代码生成器的编写等.比如把数据库的表映射成go语言的struct,这些体力活,写个代码生成器是最合适不过的了. 示例例把表转成 struct : 当然这篇 ...

  2. Synchronized加锁、锁升级和java对象内存结构

    首先了解一下JMM中定义的内存操作: 一个线程操作数据时候都是从主内存(堆内存)读取到自己工作内存(线程私有的数据区域)中再进行操作.对于硬件内存来说,并没有工作内存和主内存的区分,这都是java内存 ...

  3. CentOS7编译和安装GCC7.5

    CentOS7编译和安装GCC7.5 一.    环境介绍: CentOS7 虚拟机连上了互联网(为什么要强调这点呢,因为CentOS7每次进入系统,都需要手动点击右上角的Connect,才能连上互联 ...

  4. CSS之未知高度img垂直居中

    测试代码如下:(能够水平居中,通过text-align:center实现) <style>.box{ width:800px;height:600px;border:2px solid # ...

  5. JS中各种变量类型在条件判断为false的情况

    var a = undefined; ->false var a = 0; ->false var a = 0.0; ->false var a = NaN; ->false ...

  6. Win10最常用的快捷键,效率Max提高100%(常用的应该是最全的)

    写在最前面 这是博主爆肝了一晚上给写出来,因为很多博客和资料中仍然使用的xp win7 和win8 的快捷键,我不断地的实验和尝试,总结出以下的快捷键,希望可以帮助到你. 最后,未经运营,爆肝博文不得 ...

  7. Docker搭建代码检测平台SonarQube并检测maven项目

    1 前言 良好的代码习惯是一个优秀程序员应该具备的品质,但靠人的习惯与记忆来保证代码质量,始终不是一件靠谱的事.在计算机行业应该深知,只要是人为的,都会有操作风险.本文讲解如何通过Docker搭建代码 ...

  8. 「雕爷学编程」Arduino动手做(13)——触摸开关模块

    37款传感器和模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器与模块,依照实践出真知(动手试试)的理念,以学习和交流为目的,这里准备 ...

  9. Appium自动化(10) - appium高级元素定位方式之 UI Automator API 的详解

    如果你还想从头学起Appium,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1693896.html 前言 前面介绍过根据id,clas ...

  10. php RSA和AES加密算法

    一.RSA加密 RSA只说PHP中的应用,详细的算法原理解释,请自行百度,或者参考(RSA加密算法-详细解释以及公钥加密为什么每次都不一样) 总结:公钥加密.私钥解密.私钥签名.公钥验签. 注意: 1 ...