zoukankan      html  css  js  c++  java
  • LOJ#2044. 「CQOI2016」* 数位dp

    这次的状态十分复杂,写递推版不现实.   

    于是学了一下递归版数位dp,感觉比递推版高明多了,好写还好想.  

    如果以后碰到状态复杂的数位dp的话可以考虑递归版本.   

    code: 

    #include <bits/stdc++.h>  
    #define ll long long 
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;   
    int num[20],cnt; 
    ll dp[20][20][20][2][2][2][2],L,R;    
    // dp[当前位置][前一个位置的数][前 2 个位置的数][是否合法][有 4][有 8][是否顶上界]   
    ll calc(int pos,int a,int b,bool state,bool f,bool e,bool li) 
    {
        if(f&&e) return 0;   
        if(!pos) return state;   
        if(!li&&dp[pos][a][b][state][f][e][li]!=-1)   
            return dp[pos][a][b][state][f][e][li];  
        ll det=0;    
        int m=li?num[pos]:9;    
        for(int i=0;i<=m;++i)  
            det+=calc(pos-1,i,a,state||(i==a&&i==b),f||(i==4),e||(i==8),li&&(i==m));    
        if(!li) dp[pos][a][b][state][f][e][li]=det;    
        return det; 
    }    
    ll sol(ll x) 
    { 
        cnt=0,memset(num,0,sizeof(num));  
        do
        {
            num[++cnt]=x%10; 
            x/=10; 
        }while(x);    
        if(cnt!=11) return 0; 
        ll ans=0; 
        memset(dp,-1,sizeof(dp));          
        for(int i=1;i<=num[cnt];++i)  
            ans+=calc(cnt-1,i,0,0,i==4,i==8,i==num[cnt]);   
        return ans;  
    }
    int main() 
    { 
        // setIO("input");     
        scanf("%lld%lld",&L,&R);   
        printf("%lld
    ",sol(R)-sol(L-1));   
        return 0; 
    }
    

      

  • 相关阅读:
    uva 11294 Wedding
    uvalive 4452 The Ministers’ Major Mess
    uvalive 3211 Now Or Later
    uvalive 3713 Astronauts
    uvalive 4288 Cat Vs. Dog
    uvalive 3276 The Great Wall Game
    uva 1411 Ants
    uva 11383 Golden Tiger Claw
    uva 11419 SAM I AM
    uvalive 3415 Guardian Of Decency
  • 原文地址:https://www.cnblogs.com/guangheli/p/13098134.html
Copyright © 2011-2022 走看看