给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数。
例如:n = 12,包含了5个1。1,10,12共包含3个1,11包含2个1,总共5个1。
Input
输入N(1 <= N <= 10^9)
Output
输出包含1的个数
Input示例
12
Output示例
5
dp问题dp[i][j]表示从1到i位以j开头的有多少个1。比如dp[3][4]就是1-499有多少个1。状态有dp[i][j] = dp[i][j-1] + dp[i-1][9]。
当j=1 时,dp[i][j]要加上10^(i-1),还有dp[i][0]= dp[i-1][9]+1。
那个一个数字,比如1357可以分成1000,300,50,7,答案就是dp[1][6]+dp[2][4]+dp[3][2]+d[4][0]+n-257 首字母为1的判断下。
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 #define ll long long 6 using namespace std; 7 int dp[12][12]; 8 int main() { 9 int ans = 1, n; 10 for(int i = 1; i < 10;i ++) { 11 dp[i][0] = dp[i-1][9]+1; 12 for(int j = 1; j < 10; j ++) { 13 dp[i][j] = dp[i][j-1] + dp[i-1][9]; 14 if(j == 1) dp[i][j] += ans -1; 15 } 16 ans *= 10; 17 } 18 cin >> n; 19 int m = n, cnt = 0; 20 while(m) { 21 cnt++; 22 m /= 10; 23 } 24 m = 1, ans = 0; 25 for(int i = 1; i < cnt; i ++) m *= 10; 26 while(cnt) { 27 int x = n/m; 28 if(x) { 29 ans += dp[cnt][x-1]; 30 if(x == 1) ans += (n-x*m); 31 } 32 cnt--; 33 n -= m*x; 34 m/=10; 35 } 36 cout << ans << endl; 37 return 0; 38 }