zoukankan      html  css  js  c++  java
  • fzu 2113 数位dp

    #include<stdio.h>
    #include<string.h>
    #define N 20
    #define ll __int64
    ll dp[N][N];//最多记忆400种情况
    ll digit[N];
    ll dfs(ll len,ll cnt,ll ok) {
     if(!len) return cnt;
     if(!ok&&dp[len][cnt]!=-1)
        return dp[len][cnt];
     ll i,ans=0,maxx=ok?digit[len]:9;
     for(i=0;i<=maxx;i++) {
        if(i==1)ans+=dfs(len-1,cnt+1,ok&&i==maxx);
        else
            ans+=dfs(len-1,cnt,ok&&i==maxx);
     }
     if(!ok)
        dp[len][cnt]=ans;
     return ans;
    }
    ll f(ll n) {
    ll len=0;
    while(n) {
        digit[++len]=n%10;
        n/=10;
    }
    return dfs(len,0,1);
    }
    int main() {
          ll n,m,k;
          memset(dp,-1,sizeof(dp));
          while(scanf("%I64d%I64d",&n,&m)!=EOF) {
                if(n>m) {
                    k=n;
                    n=m;
                    m=k;
                }
            printf("%I64d
    ",f(m)-f(n-1));
          }
    return 0;}
    
    <pre name="code" class="cpp">/*
    数位dp
    直接相加更快
    另一种思路
    */
    #include<stdio.h>
    #include<string.h>
    #define N 20
    #define ll __int64
    ll lower[N];//储存十的倍数。
    ll dp[N][10];
    ll digit[N];
    ll  rest[N];//用来储存有多少数
    ll dfs(ll len,ll cnt,ll ok) {
       if(!len) return cnt==1?1:0;
       if(!ok&&dp[len][cnt]!=-1)
        return dp[len][cnt];
       ll i,ans=0,maxx=ok?digit[len]:9;
       for(i=0;i<=maxx;i++)
        ans+=dfs(len-1,i,ok&&i==maxx);
       if(cnt==1) {
        if(!ok)
            ans+=lower[len];
        else
            ans+=rest[len];//
       }
       if(!ok)
        dp[len][cnt]=ans;
       return ans;
    }
    ll f(ll n) {
    ll len=0;
    ll z=n;
    while(n) {
        digit[++len]=n%10;
        rest[len]=z%lower[len]+1;//比如是163的话,因为从100-163所以取余后要加一
        n/=10;
    }
    return dfs(len,0,1);
    }
    int main() {
          ll i,n,m;
          lower[0]=1;
          memset(dp,-1,sizeof(dp));
          for(i=1;i<=19;i++)
            lower[i]=lower[i-1]*10;
          while(scanf("%I64d%I64d",&n,&m)!=EOF) {
            printf("%I64d
    ",f(m)-f(n-1));
          }
    return 0;}
    


    
    
  • 相关阅读:
    C语言字符编码处理
    Linux gperf命令
    C语言命令行处理
    深入分析Java ClassLoader原理
    微软Build2016:Xamarin杂记
    Ubuntu下配置Tomcat以指定(非root)身份执行
    Android之弹出多级菜单
    OC基础:Date
    Linux IO 多路复用是什么意思?
    c语言实现输出一个数的每一位
  • 原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410584.html
Copyright © 2011-2022 走看看