【POJ 3252】 Round Numbers

【POJ 3252】 Round Numbers


组合数学里的题。。在我飞的引导下走上了数位dp的不归路。。。这样算不算开挂。。。。好羞涩


数位dp真的真的真的好好用!!!

数位dp真的真的真的好好用!!!

数位dp真的真的真的好好用!!!


重要的事说三遍 一入数位dp深似海 再也粗不来了。。。 用数位很好想……都不知道该怎么写题解。。。


代码如下:


#include <iostream>
#include <cstdio>
#include <cstring>
#define ll long long

using namespace std;

int dp[31][2][63];
int digit[31];

/*
big 0 1 平衡 防止负从31开始
hs 前导0
*/

int dfs(int pos,int big,bool hs,bool high)
{
    if(pos == -1) return big >= 31;
    if(!high && ~dp[pos][hs][big]) return dp[pos][hs][big];

    int i,en,ans = 0,nbig;
    bool nhs;
    en = high? digit[pos]: 1;
    for(i = 0; i <= en; ++i)
    {
        nbig = big, nhs = hs;
        if(i)
        {
            nbig--;
            nhs = 0;
        }
        else if(!hs) nbig++;

        ans += dfs(pos-1,nbig,nhs,high && i == en);
    }

    if(!high) dp[pos][hs][big] = ans;
    return ans;
}

int Solve(ll x)
{
    int len = 0;
    while(x)
    {
        digit[len++] = x%2;
        x >>= 1;
    }
    return dfs(len-1,31,1,1);
}

int main()
{
    memset(dp,-1,sizeof(dp));
    ll st,en;/////////////////这里必须吐槽下…………今天不宜敲代码 上午数组开小了 hdoj的题 不断WA 这次还好 ll开成int 最关键输入还用的%lld。。。然后给了RE 找了半天突然发现了TOT
    scanf("%lld %lld",&st,&en);
    printf("%d\n",Solve(en) - Solve(st-1));
    return 0;
}


你可能感兴趣的:(数位dp)