• 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));
        }
    }
    
  • 相关阅读:
    location.replace与location.href,location.reload的区别
    JavaScript 中 this 的用法
    setTimeout 的用法
    ngRoute 和 ui.router 的使用方法和区别
    js正则匹配只能输入有效数字可加小数点
    正则表达式
    关于浮动与清除浮动
    当给一个元素的宽度设置为百分比的时候,百分比的计算值是由它的直接父级元素的宽度决定
    内联(行级)元素不能设置margin-top
    JS判断数据是否是JSON类型
  • 原文地址:https://www.cnblogs.com/maoruimas/p/9710774.html
Copyright © 2020-2023  润新知