POJ3252:Round Numbers(数位DP+记忆化DFS)
2013-08-18 21:41
323 查看
Description
Thecows,asyouknow,havenofingersorthumbsandthusareunabletoplayScissors,Paper,Stone'(alsoknownas'Rock,Paper,Scissors','Ro,Sham,Bo',andahostofothernames)inordertomakearbitrarydecisionssuchaswhogetstobemilkedfirst.Theycan'tevenflipacoinbecauseit'ssohardtotossusinghooves.
Theyhavethusresortedto"roundnumber"matching.Thefirstcowpicksanintegerlessthantwobillion.Thesecondcowdoesthesame.Ifthenumbersareboth"roundnumbers",thefirstcowwins,
otherwisethesecondcowwins.
ApositiveintegerNissaidtobea"roundnumber"ifthebinaryrepresentationofNhasasmanyormorezeroesthanithasones.Forexample,theinteger9,whenwritteninbinaryform,is1001.1001hastwozeroesandtwoones;thus,9isaroundnumber.Theinteger26is11010inbinary;sinceithastwozeroesandthreeones,itisnotaroundnumber.
Obviously,ittakescowsawhiletoconvertnumberstobinary,sothewinnertakesawhiletodetermine.Bessiewantstocheatandthinksshecandothatifsheknowshowmany"roundnumbers"areinagivenrange.
Helpherbywritingaprogramthattellshowmanyroundnumbersappearintheinclusiverangegivenbytheinput(1≤Start<Finish≤2,000,000,000).
Input
Line1:Twospace-separatedintegers,respectively
Startand
Finish.
Output
Line1:Asingleintegerthatisthecountofroundnumbersintheinclusiverange
Start..
Finish
SampleInput
SampleOutput
#include<stdio.h>
#include<string.h>
#include<algorithm>
usingnamespacestd;
intdp[50][50][50],bit[50];
//dp[k][i][j],k为长度,i,为0的个数,j为1的个数
intdfs(intpos,intnum0,intnum1,intwork,intfirst)
{
if(!pos)
{
if(first)
return1;
if(num0>=num1)
return1;
return0;
}
if(!first&&!work&&dp[pos][num0][num1]!=-1)//已经被访问过了
returndp[pos][num0][num1];
intend=work?bit[pos]:1;//判断此位能否为1
intans=0;
for(inti=0;i<=end;i++)
{
//doing&&end==i是看此位是不是算完
if(first)//first是看第一位是否放下
{
if(i==0)
ans+=dfs(pos-1,0,0,work&&end==i,1);//第一位还未放下,继续往后面看
else
ans+=dfs(pos-1,num0,num1+1,work&&end==i,0);//在这个选定的位置放下1,作为次二进制的初始
}
else
{
if(i==0)
ans+=dfs(pos-1,num0+1,num1,work&&end==i,0);//在二进制后面放0
else
ans+=dfs(pos-1,num0,num1+1,work&&end==i,0);//放1
}
}
if(!work&&!first)
dp[pos][num0][num1]=ans;//记录,防止重复访问,节省时间
returnans;
}
intsolve(intn)
{
intlen=1;
while(n)
{
bit[len++]=n&1;
n>>=1;
}
intans=dfs(len-1,0,0,1,1);
returnans;
}
intmain()
{
memset(dp,-1,sizeof(dp));
intl,r;
while(~scanf("%d%d",&l,&r))
{
printf("%d\n",solve(r)-solve(l-1));
}
return0;
}
Thecows,asyouknow,havenofingersorthumbsandthusareunabletoplayScissors,Paper,Stone'(alsoknownas'Rock,Paper,Scissors','Ro,Sham,Bo',andahostofothernames)inordertomakearbitrarydecisionssuchaswhogetstobemilkedfirst.Theycan'tevenflipacoinbecauseit'ssohardtotossusinghooves.
Theyhavethusresortedto"roundnumber"matching.Thefirstcowpicksanintegerlessthantwobillion.Thesecondcowdoesthesame.Ifthenumbersareboth"roundnumbers",thefirstcowwins,
otherwisethesecondcowwins.
ApositiveintegerNissaidtobea"roundnumber"ifthebinaryrepresentationofNhasasmanyormorezeroesthanithasones.Forexample,theinteger9,whenwritteninbinaryform,is1001.1001hastwozeroesandtwoones;thus,9isaroundnumber.Theinteger26is11010inbinary;sinceithastwozeroesandthreeones,itisnotaroundnumber.
Obviously,ittakescowsawhiletoconvertnumberstobinary,sothewinnertakesawhiletodetermine.Bessiewantstocheatandthinksshecandothatifsheknowshowmany"roundnumbers"areinagivenrange.
Helpherbywritingaprogramthattellshowmanyroundnumbersappearintheinclusiverangegivenbytheinput(1≤Start<Finish≤2,000,000,000).
Input
Line1:Twospace-separatedintegers,respectively
Startand
Finish.
Output
Line1:Asingleintegerthatisthecountofroundnumbersintheinclusiverange
Start..
Finish
SampleInput
212
SampleOutput
6
这道题还是花了不少的时间啊,本人愚笨,看了大神的代码没看懂,经过一个半小时的推敲理解,将搜索过程列出之后总算理解了他的思想
题意:算出区间内二进制中0的个数大于等于1的个数的数字有多少个
思路:数位DP确实是一个很巧妙的东西,在搜索过程中,我们要先确定首位1的放置,然后再根据这个首位去对后面所有位置的放置情况进行一次搜索即可
#include<string.h>
#include<algorithm>
usingnamespacestd;
intdp[50][50][50],bit[50];
//dp[k][i][j],k为长度,i,为0的个数,j为1的个数
intdfs(intpos,intnum0,intnum1,intwork,intfirst)
{
if(!pos)
{
if(first)
return1;
if(num0>=num1)
return1;
return0;
}
if(!first&&!work&&dp[pos][num0][num1]!=-1)//已经被访问过了
returndp[pos][num0][num1];
intend=work?bit[pos]:1;//判断此位能否为1
intans=0;
for(inti=0;i<=end;i++)
{
//doing&&end==i是看此位是不是算完
if(first)//first是看第一位是否放下
{
if(i==0)
ans+=dfs(pos-1,0,0,work&&end==i,1);//第一位还未放下,继续往后面看
else
ans+=dfs(pos-1,num0,num1+1,work&&end==i,0);//在这个选定的位置放下1,作为次二进制的初始
}
else
{
if(i==0)
ans+=dfs(pos-1,num0+1,num1,work&&end==i,0);//在二进制后面放0
else
ans+=dfs(pos-1,num0,num1+1,work&&end==i,0);//放1
}
}
if(!work&&!first)
dp[pos][num0][num1]=ans;//记录,防止重复访问,节省时间
returnans;
}
intsolve(intn)
{
intlen=1;
while(n)
{
bit[len++]=n&1;
n>>=1;
}
intans=dfs(len-1,0,0,1,1);
returnans;
}
intmain()
{
memset(dp,-1,sizeof(dp));
intl,r;
while(~scanf("%d%d",&l,&r))
{
printf("%d\n",solve(r)-solve(l-1));
}
return0;
}
相关文章推荐
- POJ3252:Round Numbers(数位DP+记忆化DFS)
- HDU3709:Balanced Number(数位DP+记忆化DFS)
- Round Numbers(数位dp+dfs+记忆化模板)
- HDU3709:Balanced Number(数位DP+记忆化DFS)
- HDU-3709-Balanced Number(数位DP+记忆化DFS)
- hdu3555 Bomb 【数位dp+记忆化dfs】
- Codeforces Beta Round #77 (Div. 1 Only), problem: (B) Lucky Numbers 数位DP+剪枝DFS+贪心
- poj3252 Round Numbers (数位dp)
- poj3252 - Round Numbers(数位dp)
- HDU - 4734 F(x) (数位DP&记忆化dfs)
- 【POJ3252】Round Numbers(数位DP)
- HDU - 2089 不要62 (数位DP&记忆化dfs)水
- HDU - 3652 HDU - 3652 (数位DP&记忆化dfs)
- POJ3252 Round Numbers 【数位dp】
- HDU - 4352 XHXJ's LIS (数位DP&记忆化dfs&位运算)好题
- [poj3252]Round Numbers_数位dp
- 历届试题 地宫取宝 (DP+记忆化DFS)
- HDU - 4507 吉哥系列故事——恨7不成妻 (数位DP&记忆化dfs)好题
- POJ3252:Round Numbers(数位DP)
- POJ3252 Round Numbers 数位DP