POJ 3252Round Numbers(数位DP)
来源:互联网 发布:大淘客数据接口怎么用 编辑:程序博客网 时间:2024/06/05 11:58
POJ 3252Round Numbers
题目大意
如果一个数的二进制中0的数目大于等于1那么就称这个数为Round Number,问你区间[L,R]中有多少Round Number,
(1≤L,R≤2∗109)
分析
问题可以转化成问从1到n有多少个Round Number
用f[i]表示
接下来就是状态的转移了,状态的转移稍微麻烦一点,
比如1010
然后1000~1001
最后1010~1010
大概就是这个思路,具体见代码。
一开始交了几发WA后手动测试几组小数据都对了,看代码后发现有些int应该改成long long int,改后又WA,查了一会差不出,到网上找了份AC代码对拍发现131072后的数据就不对了,这么小不会是int的问题,最后才发现是dp[i][j]数组中j开小了。
这道题折腾了我快一天了,心累。
我的方法不太优美,可以参考这篇POJ3252:Round Numbers(数位DP+记忆化DFS)
代码
#include<cstdio>#include<iostream>#include<cmath>#include<cstring>#include<cstdlib>#include<queue>using namespace std;#define LL long long intLL Start,Finish;LL dp[35][70];//dp[i][j]表示长为i,0和1的数目差为j的情况数,j为31时表示01差的数目为0LL f[35];//f[i]表示2^i之前(不包含2^i)的Round Number数目void Dp(){ dp[1][32]=1;//边界 dp[1][30]=1; for(int i=2;i<=31;i++)//总长为i的情况 for(int k=1;k<=i-1;k++)//长为k的情况 for(int j=31-i;j<=31+i;j++)//0和1差的数目 dp[i][i-k-1-1+j]+=dp[k][j];}void Get_f(){ f[0]=1;//边界 LL temp_ans=0; for(int i=1;i<=31;i++) { for(int j=31;j<=31+i;j++) temp_ans+=dp[i][j]; f[i]=temp_ans; } }void To2(LL n,int b[],int &lenth)//将n转换成二进制存到b数组中,下标从0开始,lenth是最终二进制长度{ lenth=0; while(n) { b[lenth++]=n%2; n=n/2; }}LL Solve(LL n)//求从0到n有多少Round number{ if(n<=1)return 1; LL ans=0; int b[35]; int lenth; To2(n,b,lenth); int diff=-1;//到目前为止的01差 ans=f[lenth-1]; for(int loc=lenth-2;loc>=0;loc--) { if(loc==0)//边界 { if(b[loc]==1 ) { if(diff-1>=0)ans++; if(diff+1>=0)ans++; } else if(b[loc]==0 && diff+1>=0)ans++; return ans; } if(b[loc]==1) { for(int i=1;i<=loc;i++) for(int j=31-i;j<=31+i;j++) if(diff+j+loc+1-i>=31) ans+=dp[i][j]; diff--; } else diff++; } return ans;}int main(){ //freopen("data.in","r",stdin); //freopen("data1.out","w",stdout); LL ans; Dp(); Get_f(); while(scanf("%lld%lld",&Start,&Finish)!=EOF) { ans=Solve(Finish)-Solve(Start-1); printf("%lld\n",ans); }}
0 0
- poj 3252 Round Numbers(数位dp)
- poj 3252 Round Numbers(数位dp)
- POJ 3252 round numbers(数位DP)
- POJ 3252 Round Numbers(数位dp)
- POJ 3252 Round Numbers (数位dp)
- POJ 3252 Round Numbers(数位DP)
- POJ-3252 Round Numbers (数位DP)
- POJ 3252 - Round Numbers(数位dp)
- POJ 3252 Round Numbers(数位 DP)
- poj 3252 Round Numbers (数位DP)
- POJ 3252 Round Numbers (数位dp)
- POJ 3252Round Numbers(数位DP)
- POJ 3252 Round Numbers(数位dp)
- poj 3252 Round Numbers(数位dp)
- poj 3252 Round Numbers(数位DP)
- POJ 3252Round Numbers(数位dp)
- POJ 3252 Round Numbers (数位dp)
- POJ 3252 Round Numbers(数位DP)
- 数据结构基础知识1
- LeetCode题解:Arithmetic Slices
- Javaweb程序服务器部署
- 浅谈C++KeyboardProc|LowLevelKeyboardProc函数使用
- 13.13
- POJ 3252Round Numbers(数位DP)
- c++ Vector 使用心得
- HDU - 1086.You can Solve a Geometry Problem too
- Validation校验(二)
- Universal-ImageLoader源码流程浅析之(一)--参数配置及主要参数说明
- 斯诺登的密码
- PHP数据库 mysql(三)
- codevs天梯 cantor表 找规律
- 问题六十四:怎么用C++实现二叉查找树(binary search tree)及其相关操作