HDU 5898 odd-even number

初稿

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=30;
ll OddNormal[maxn],EvenNormal[maxn],OddOdd[maxn],EvenEven[maxn],normal[maxn];
int a[maxn],len;
ll five[maxn];
void init()
{
    five[0]=1;for(int i=1;i<20;++i)five[i]=5*five[i-1];

    OddNormal[0]=EvenNormal[0]=1;
    for(int n=1;n<20;++n)
    {
        OddNormal[n]=EvenNormal[n]=0;
        for(int i=2;i<=n/2*2;i=i+2)OddNormal[n]=OddNormal[n]+five[i]*EvenNormal[n-i];
        for(int i=1;i<(n+1)/2*2;i=i+2)EvenNormal[n]=EvenNormal[n]+five[i]*OddNormal[n-i];
    }

    for(int n=1;n<20;++n)
    {
        OddOdd[n]=EvenEven[n]=0;
        for(int i=2;i<=n/2*2;i=i+2)EvenEven[n]=EvenEven[n]+five[i]*OddNormal[n-i];
        for(int i=1;i<(n+1)/2*2;i=i+2)OddOdd[n]=OddOdd[n]+five[i]*EvenNormal[n-i];
    }

    normal[1]=5;
    for(int n=2;n<20;++n)
    {
        normal[n]=5*OddOdd[n-1]+4*EvenEven[n-1]+4*OddNormal[n-1];
        normal[n]=normal[n]+normal[n-1];
    }
}
inline int countodd(int x)
{
    return x/2;
}
inline int counteven(int x)
{
    if(x==0)return 0;
    return (x-1)/2+1;
}
ll calc()
{
    if(len==1)return counteven(a[1]+1);
    ll ret=normal[len-1]+countodd(a[len])*OddOdd[len-1]+(counteven(a[len])-1)*(OddNormal[len-1]+EvenEven[len-1]);
    int cnt=1;
    for(int i=len-1;i>0;--i)
    {
        if(cnt&1)
        {
            if(a[i+1]&1)
            {
                if(i==1)ret=ret+countodd(a[1]+1);
                else ret=ret+countodd(a[i])*(EvenNormal[i-1]+OddNormal[i-1]);
                if(a[i]%2==0)break;
            }
            else
            {
                if(i==1)break;
                ret=ret+countodd(a[i])*OddOdd[i-1]+counteven(a[i])*EvenNormal[i-1];
            }
        }
        else
        {
            if(a[i+1]&1)
            {
                if(i==1)ret=ret+counteven(a[1]+1);
                else ret=ret+countodd(a[i])*OddOdd[i-1]+counteven(a[i])*(OddNormal[i-1]+EvenEven[i-1]);
            }
            else
            {
                if(i==1)ret=ret+counteven(a[1]+1);
                else ret=ret+counteven(a[i])*(OddNormal[i-1]+EvenEven[i-1]);
                if(a[i]&1)break;
            }
        }
        if(a[i]%2==a[i+1]%2)cnt++;
        else cnt=1;
    }
    return ret;
}
int f(ll x)
{
    len=0;
    while(x)
    {
        a[++len]=x%10;
        x=x/10;
    }
    return 0;
}
int main()
{
    //freopen("Input.txt","r",stdin);
    init();
    ll l,r,ansl,ansr;
    int t;scanf("%d",&t);
    for(int Case=1;Case<=t;++Case)
    {
        scanf("%I64d%I64d",&l,&r);
        ansl=ansr=0;
        f(r);ansr=calc();
        //printf("ansr=%I64d
",ansr);
        if(l==1)ansl=1;
        else{f(l-1);ansl=calc();}
        //printf("ansl=%I64d
",ansl);
        printf("Case #%d: %I64d
",Case,ansr-ansl);
    }
}

参考网上代码学习数位dp的代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ms(s,a) memset(s,a,sizeof(s))
#define debug(x) cout<<"< "#x" = "<<x<<" >
"
int len,a[20];
ll dp[20][20][2][2];//TODO
ll dfs(int pos,int cnt,bool odd,bool lim,bool zero)
{
    if(!pos)return odd^(cnt&1);
    if(!lim&&dp[pos][cnt][odd][zero]!=-1)return dp[pos][cnt][odd][zero];
    ll ret=0;
    int _max=lim?a[pos]:9;
    for(int i=0;i<=_max;++i)
    {
        if(zero)
        {
            if(i==0)ret+=dfs(pos-1,1,0,0,1);
            else ret+=dfs(pos-1,1,i&1,lim&&i==_max,0);
        }
        else
        {
            if(odd==(i&1))ret+=dfs(pos-1,cnt+1,i&1,lim&&i==_max,0);
            else
            {
                if(odd==(cnt&1))continue;
                ret+=dfs(pos-1,1,i&1,lim&&i==_max,0);
            }
        }
    }
    if(!lim)dp[pos][cnt][odd][zero]=ret;
    return ret;
}
ll calc(ll x)
{
    if(x==0)return 1;
    len=0;
    while(x)
    {
        a[++len]=x%10;
        x/=10;
    }
    return dfs(len,0,0,1,1);//check it later!
}
int main() 
{
    //freopen("Input.txt","r",stdin);
    ms(dp,-1);
    int t;scanf("%d",&t);
    ll l,r;
    for(int Case=1;Case<=t;++Case)
    {
        scanf("%I64d%I64d",&l,&r);
        printf("Case #%d: %I64d
",Case,calc(r)-calc(l-1));
    }
}
原文地址:https://www.cnblogs.com/maoruimas/p/9710774.html