题意:给一个最大2^64的数字,问从1到这个数字共有多少个数字中含有‘49’,输出个数。
题解:数位dp基础题,dp数组第一维还是pos,第二维判断前一位是否是4,第三维是是否出现了49,从而使枚举的数字唯一。
#include <stdio.h>
#include <string.h>
const int N = 30;
__int64 f[N][2][2];
int num[N];
__int64 dp(int pos, bool is4, bool flag, bool limit, bool ok) {
if (pos == -1 && ok)
return 1;
else if (pos == -1)
return 0;
if (!limit && f[pos][is4][ok] != -1)
return f[pos][is4][ok];
int end = limit ? num[pos] : 9;
__int64 ans = 0;
for (int i = 0; i <= end; i++) {
if (i == 0 && flag)
ans += dp(pos - 1, 0, 1, limit && i == end, ok);
else if (i == 9 && is4)
ans += dp(pos - 1, 0, 0, limit && i == end, 1);
else if (i == 4)
ans += dp(pos - 1, 1, 0, limit && i == end, ok);
else
ans += dp(pos - 1, 0, 0, limit && i == end, ok);
}
if (!limit)
f[pos][is4][ok] = ans;
return ans;
}
__int64 solve(__int64 n) {
int pos = 0;
while (n) {
num[pos++] = n % 10;
n /= 10;
}
return dp(pos - 1, 0, 1, 1, 0);
}
int main() {
int t;
__int64 n;
scanf("%d", &t);
while (t--) {
memset(f, -1, sizeof(f));
scanf("%I64d", &n);
printf("%I64d\n", solve(n));
}
return 0;
}