The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the time bomb. The number sequence of the time bomb counts from 1 to N. If the current number sequence includes the sub-sequence "49", the
power of the blast would add one point.
Now the counter-terrorist knows the number N. They want to know the final points of the power. Can you help them?
Now the counter-terrorist knows the number N. They want to know the final points of the power. Can you help them?
The input terminates by end of file marker.
3 1 50 500
0
1
15
From 1 to 500, the numbers that include the sub-sequence "49" are "49","149","249","349","449","490","491","492","493","494","495","496","497","498","499", so the answer is 15.
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <map>
#include <vector>
using namespace std;
int a[25];
long long dp[25][2][12];//当前位数,是否已包含49,前一位是几
// 当前位置 是否包含49。 前一位 限制位
long long dfs(int pos, bool have, int pre, bool limit) {
//如果已枚举完,并且已经包含49 则输出1,否则0了。
if (pos == -1) return have;
//记忆化dp的正确姿势
if (!limit && dp[pos][have][pre] != -1) return dp[pos][have][pre];
int up = limit ? a[pos] : 9;
long long temp = 0;
for (int i = 0; i <= up; ++i) {
if (pre == 4 && i == 9) {//存在49的状态
temp += dfs(pos-1, true, i, limit && i == a[pos]);
} else { //不存在49的状态
temp += dfs(pos-1, have, i, limit && i == a[pos]);
}
}
if (!limit)
dp[pos][have][pre] = temp;
return temp;
}
long long solve(long long x) {
int i = 0;
while (x) {
a[i++] = x%10;
x /= 10;
}
return dfs(i-1, false, 0, 1);
}
int main() {
int T;
long long shit;
cin >> T;
while (T--) {
memset(dp, -1, sizeof(dp));
cin >>shit;
cout << solve(shit) << endl;
}
}