数位DP(组合数打表)—— Round Numbers ( POJ 3252 )
2016-07-20 20:15
417 查看
题目链接:
http://poj.org/problem?id=3252
分析:
求出S~F中转换成二进制数后0的个数≥1的个数的数字的个数。0的个数大于1的个数的数可以用组合数来做。
题解:
算出1~F+1和1~S的满足条件的个数相减即可。
先一个数转换乘二进制形式存入数组中:
然后先将长度小于number[0]的所有满足条件的数算出,这个非常简单,就是满足C(≥(len/2), len)(从len个数中挑≥(len/2)个)的所有数就是题意。
再将number[0]长度下满足条件的数计算出来,从最高位往下搜索即可:
AC代码:
http://poj.org/problem?id=3252
分析:
求出S~F中转换成二进制数后0的个数≥1的个数的数字的个数。0的个数大于1的个数的数可以用组合数来做。
题解:
算出1~F+1和1~S的满足条件的个数相减即可。
先一个数转换乘二进制形式存入数组中:
void change(int n) { number[0]=0; //nubmer[0]用来存储二进制数总长度 while(n) { number[++number[0]]=n%2;//逆序存储二进制数 n/=2; } return; }
然后先将长度小于number[0]的所有满足条件的数算出,这个非常简单,就是满足C(≥(len/2), len)(从len个数中挑≥(len/2)个)的所有数就是题意。
再将number[0]长度下满足条件的数计算出来,从最高位往下搜索即可:
int round(int n) { int i,j; int sum=0; //比十进制数n小的所有RN数 change(n); //cout << number[0] << endl; /*计算长度小于number[0]的所有二进制数中RN的个数*/ for(i=1;i<number[0]-1;i++) for(j=i/2+1;j<=i;j++) sum += dp[i][j]; /*计算长度等于number[0]的所有二进制数中RN的个数*/ int zero=0; //从高位向低位搜索过程中出现0的位的个数 for(i=number[0]-1;i>=1;i--) if(number[i]) //当前位为1 for(j=(number[0]+1)/2-(zero+1);j<=i-1;j++)//前面已经出现zero个0了,所以需要减去它 sum+=dp[i-1][j]; else zero++; return sum; }
AC代码:
#include<iostream> using namespace std; int dp[33][33]={0}; int f[33][33]; int number[35]; void init() { for(int i=0;i<=32;i++) for(int j=0;j<=i;j++) { if(!j || i==j) dp[i][j] = 1; else dp[i][j] = dp[i-1][j-1] + dp[i-1][j]; //cout << i << " " << j << ": " << dp[i][j] << endl; } return; } /*十进制n转换二进制,逆序存放到number[]*/ void change(int n) { number[0]=0; while(n) { number[++number[0]]=n%2; n/=2; } return; } /*计算比十进制数n小的所有RN数*/ int round(int n) { int i,j; int sum=0; //比十进制数n小的所有RN数 change(n); //cout << number[0] << endl; /*计算长度小于number[0]的所有二进制数中RN的个数*/ for(i=1;i<number[0]-1;i++) for(j=i/2+1;j<=i;j++) sum += dp[i][j]; /*计算长度等于number[0]的所有二进制数中RN的个数*/ int zero=0; //从高位向低位搜索过程中出现0的位的个数 for(i=number[0]-1;i>=1;i--) if(number[i]) //当前位为1 for(j=(number[0]+1)/2-(zero+1);j<=i-1;j++) sum+=dp[i-1][j]; else zero++; return sum; } int main() { init(); int a,b; cin>>a>>b; cout<<round(b+1)-round(a)<<endl; return 0; }
相关文章推荐
- mysql binlog二进制日志详解
- C语言二进制思想以及数据的存储
- 详解C++编程中对二进制文件的读写操作
- 整理C# 二进制,十进制,十六进制 互转
- 在ASP.NET 2.0中操作数据之五十四:添加新记录时包含一个文件上传选项
- c#二进制逆序方法详解
- JS幻想 读取二进制文件第1/2页
- 使用jscript实现二进制读写脚本代码
- JavaScript读二进制文件并用ajax传输二进制流的方法
- C#中图片、二进制与字符串的相互转换方法
- C#二进制序列化实例分析
- JavaScript前端开发之实现二进制读写操作
- PHP函数篇详解十进制、二进制、八进制和十六进制转换函数说明
- javascript 二进制运算技巧解析
- 如何判断一个整数的二进制中有多少个1
- MSSQL 将截断字符串或二进制数据问题的解决方法
- 二进制中1的个数
- C++ 十进制转换为二进制的实例代码
- C语言十进制转二进制代码实例
- asp.net实现图片以二进制流输出的两种方法