题目要求求出在
[
0
,
B
]
[0,B]
[0,B]内
F
(
x
)
≤
F
(
A
)
F(x)\le F(A)
F(x)≤F(A)的
x
x
x个数。
很自然会联想到用数位
d
p
dp
dp来解决。
观察
F
(
A
)
F(A)
F(A)的形式。
题目给出了
F
(
A
)
=
∑
i
=
1
n
A
i
2
i
−
1
F(A)=\sum\limits_{i=1}^nA_i2^{i-1}
F(A)=i=1∑nAi2i−1;联想到有
A
=
∑
i
=
1
n
A
i
1
0
i
−
1
A=\sum\limits_{i=1}^nA_i10^{i-1}
A=i=1∑nAi10i−1。
那么
F
(
A
)
F(A)
F(A)要怎么嵌入数位
d
p
dp
dp?
注意到
n
≤
9
n\le9
n≤9有
F
(
A
)
≤
4599
F(A)\le4599
F(A)≤4599,或许可以把
F
(
x
)
F(x)
F(x)存进状态里面
这样的话就是
f
(
d
i
g
i
t
,
F
x
)
f(digit,Fx)
f(digit,Fx)表示
d
i
g
i
t
digit
digit位后,
F
(
x
)
≤
F
x
F(x)\le Fx
F(x)≤Fx的
x
x
x的数量
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<cctype>
using namespace std;
int A,B;
int F[12][4605];
int bit[12];
int calc(int x) {
int ret = 0, add = 1;
while (x) {
ret += x % 10 * (add <<= 1);
x /= 10;
}
return ret;
}
int dfs(const int &pos, const int &state, const bool &limit) {
if (!pos) {
return state >= 0;
}
if (state < 0) {
return 0;
}
if (!limit && F[pos][state] != -1) {
return F[pos][state];
}
int retVal = 0, up = limit ? bit[pos] : 9;
for (int i = 0; i <= up; ++i) {
retVal += dfs( pos - 1, state - i * (1 << pos), limit && i == up );
}
if (!limit) {
F[pos][state] = retVal;
}
return retVal;
}
int solve(int x,const int &y) {
bit[0] = 0;
while (x) {
bit[ ++bit[0] ] = x % 10;
x /= 10;
}
return dfs(bit[0], calc(y), true);
}
int main() {
int T;
scanf("%d", &T);
memset( F, -1, sizeof(F) );
for (int caseNumber = 1; caseNumber <= T; ++caseNumber) {
scanf( "%d%d", &A, &B);
printf( "Case #%d: %d\n", caseNumber, solve(B, A) );
}
return 0;
}