题意:给一个数N,计算从0到N的所有数中数位1的个数,。
思路:数位dp,定义dp[i][j]表示从0到以i为首位长度为j后位全是0的区间有多少数位1。
代码
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int MAX_N = 10;
char s[MAX_N];
ll dp[10][35], len;
ll ans;
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
dp[0][0] = 0;
for (int i = 1; i <= 10; i++) {
for (int j = 0; j <= 9; j++) {
if (j == 0) {
for (int k = i-1; k >= 1; k--) {
dp[j][i] += dp[9][k];
}
} else {
if (j > 1) dp[j][i] = dp[j-1][i] + dp[0][i] + (j-1==1?(ll)(pow(10, i-1)-1):0);
else dp[j][i] = dp[0][i] + 1;
}
}
}
scanf("%s", s);
len = strlen(s); ans = 0;
for (int i = 0; i < len; i++) {
if (s[i]-'0' == 0) continue;
ans += dp[s[i]-'0'][len-i];
if (s[i]-'0'==1) {
ans += (ll)atoi(s+i+1);
}
}
printf("%lld\n", ans);
return 0;
}