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