POJ 3252 Round Numbers (二进制/数位DP)

两盒软妹~` 提交于 2020-02-10 13:06:48

转化为二进制,进行dp,
记录的内容是在pos位上x个0、y个1情况下的有效数字个数,
pre消除前导0影响。

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <string>

#define lint long long
using namespace std;

lint dp[33][33][33];
lint wei[50];



lint dfs(int pos,int num0,int limit,int pre,int num1)
{
	if (pos==-1)
    return num0>=num1;

	lint ans=0;

	if (!limit&&dp[pos][num0][num1]!=-1)
    return dp[pos][num0][num1];

	int up=limit?wei[pos]:1;

	for(int i=0;i<=up;i++)
    {
        if(pre==1&&i==0)
        ans+=dfs(pos-1,num0,limit&&i==up,1,num1);
        else
        ans+=dfs(pos-1,num0+(i==0),limit&&i==up,0,num1+(i==1));
	}

	if (!limit)
	dp[pos][num0][num1]=ans;

	return ans;
}

lint solve(lint num)
{
    int i=0;

    while(num)
    {
        wei[i]=num%2;
        num/=2;
        i++;
    }
     return dfs(i-1,0,1,1,0);
}

int main()
{
    lint i,j,l,n,m,t,k;
    memset(dp,-1,sizeof dp);
    scanf("%lld%lld",&m,&n);
    printf("%lld\n",solve(n)-solve(m-1));

    return 0;
}



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!