一個正整數如果任何一個數位不大於右邊相鄰的數位,則稱為一個數位遞增的數,例如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 ; }
...