隐藏
「spoj10606」Balanced Numbers - 数位动规 | Bill Yang's Blog

路终会有尽头,但视野总能看到更远的地方。

0%

「spoj10606」Balanced Numbers - 数位动规

题目大意

    一个数被称为平衡数当且仅当对于所有出现过的数位,偶数出现奇数次,奇数出现偶数次。给定$A,B$,统计$[A,B]$中所有平衡数的个数。


题目分析

简单数位动规。
$f[i,s1,s2]$表示第$i$位,数的奇偶状态为$s1$,出现状态为$s2$。
随便转移一下即可。


代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;

typedef long long LL;

inline const LL Get_Int() {
LL num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}

int t;
LL a[25],f[25][1024][1024];

LL Dp(int Now,int status,int have,bool up,bool zero) {
if(Now<0) {
for(int i=0; i<=9; i++)
if((have&(1<<i))&&!(bool(i&1)^bool(status&(1<<i))))return 0;
return 1;
}
if(!up&&!zero&&~f[Now][status][have])return f[Now][status][have];
int Limit=up?a[Now]:9;
LL sum=0;
for(int i=Limit; i>=0; i--) {
if(zero&&i==0)sum+=Dp(Now-1,0,0,0,1);
else sum+=Dp(Now-1,status^(1<<i),have|(1<<i),(up&&i==Limit),0);
}
if(!up&&!zero)f[Now][status][have]=sum;
return sum;
}

LL Cal(LL x) {
int cnt=0;
while(x) {
a[cnt++]=x%10;
x/=10;
}
return Dp(cnt-1,0,0,1,1);
}

int main() {
memset(f,-1,sizeof(f));
t=Get_Int();
while(t--) {
LL x=Get_Int(),y=Get_Int();
printf("%lld\n",Cal(y)-Cal(x-1));
}
return 0;
}
姥爷们赏瓶冰阔落吧~