递增数

一个正整数如果任何一个数位不大于右边相邻的数位,则称为一个数位递增的数,例如1135是一个数位递增的数,而1024不是一个数位递增的数。
  给定正整数 n,请问在整数 1 至 n 中有多少个数位递增的数?
输入格式
  输入的第一行包含一个整数 n。
输出格式
  输出一行包含一个整数,表示答案。
样例输入
30
样例输出
26
评测用例规模与约定
  对于 40% 的评测用例,1 <= n <= 1000。
  对于 80% 的评测用例,1 <= n <= 100000。
  对于所有评测用例,1 <= n <= 1000000。


思路:采用数位dp,首先预处理出叶子节点的信息

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cstdio>


using namespace std ;

const int N = 12 ;

int f[N][N] ;

void init(){
    for(int i=0;i<=9;i++){//f[i,j]表示一共i位,且最高位是j的方案数的个数 
        f[1][i] = 1 ;
    }
    for(int i=2;i<N;i++){
        for(int j=0;j<=9;j++){
            for(int k=j;k<=9;k++){
                f[i][j] += f[i-1][k] ;
            }
        }
    }
}

int dp(int num){
    if(!num) return 1 ;
    vector<int> vt ;
    while(num){
        vt.push_back(num%10) ;
        num /= 10 ;
    }
    
    int last = 0, res = 0 ;
    for(int i=vt.size()-1;i>=0;i--){//dp过程对应于一颗二叉树 
        int x = vt[i] ;
        for(int j=last;j<x;j++){
            res += f[i+1][j] ;
        }
        if(x<last) break ;
        last = x ;
        if(!i) res ++ ;
    }
    return res ;
}

int main(){
    init() ;
    int n ;
    scanf("%d",&n) ;
    
    printf("%d\n",dp(n)-dp(0)) ;
    
    return 0 ;
}

 

...

posted @ 2020-03-16 17:21  gulangyuzzz  阅读(1039)  评论(0编辑  收藏  举报