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; 
    }
    

      

  • 相关阅读:
    Samara SAU ACM ICPC 2013-2014 Quarterfinal Qualification Contest
    German Collegiate Programming Contest 2013:E
    German Collegiate Programming Contest 2013:B
    LA 4975
    Codeforces Beta Round #1
    poj 3667 Hotel
    Codeforces Round #207 (Div. 2)
    【USACO 2.3.1】最长前缀
    【USACO 2.2.4】派对灯
    【USACO 2.2.3】循环数
  • 原文地址:https://www.cnblogs.com/guangheli/p/13098134.html
Copyright © 2011-2022 走看看