SPOJ BALNUM Balanced Numbers 平衡数(数位DP,状压)

题意:

  平衡树定义为“一个整数的某个数位若是奇数,则该奇数必定出现偶数次;偶数位则必须出现奇数次”,比如 222,数位为偶数2,共出现3次,是奇数次,所以合法。给一个区间[L,R],问有多少个平衡数?

思路:

  这题比较好解决,只有前导零问题需要解决。如果枚举到011,那么其前导零(偶数)出现了1次而已,而此数11却是平衡数,所以不允许前导零的出现!

  由于dfs时必定会枚举到前导零,否则位数较少的那些统计不到。状态需要3维or2维也行,3维的比较容易处理,用一维表示数位出现次数,另一维表示数位是否已经出现过了,而剩下一维自然就是位数了。乱搞一下就行了。

 1 #include <bits/stdc++.h>
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <map>
 7 #include <algorithm>
 8 #include <vector>
 9 #include <iostream>
10 #define pii pair<int,int>
11 #define INF 0x7f3f3f3f
12 #define LL long long
13 #define ULL unsigned long long
14 using namespace std;
15 const double PI  = acos(-1.0);
16 const int N=20;
17
18 LL f[N][1<<10][1<<10], bit[N];
19 //[位数][状态][是否出现过]
20
21 int isok(int s,int w)
22 {
23     if(!w)   return 0;
24     for(int i=0; i<10; i++)
25     {
26         if( i%2==0 && (w&(1<<i)) && (s&(1<<i))==0 ) return 0;    //偶数
27         if( i%2!=0 && (w&(1<<i)) && (s&(1<<i))!=0 ) return 0;
28     }
29     return 1;
30 }
31
32 LL dfs(int i,int s,int w,int sum,bool e)
33 {
34     if(i==0)            return isok(s,w);
35     if(!e&&~f[i][s][w]) return f[i][s][w];
36
37     LL ans=0;
38     int u= e? bit[i]: 9;
39     for(int d=0; d<=u; d++)
40     {
41         int ww=w, ss=s;
42         if( sum+d!=0 ) ww|=1<<d,ss^=1<<d;
43         ans+=dfs(i-1, ss, ww, sum+d, e&&d==u);
44     }
45     return e? ans: f[i][s][w]=ans;
46 }
47
48 LL cal(LL n)
49 {
50     if(n==0)    return 0;
51     int len=0, s=0;
52     while(n)    //拆数
53     {
54         bit[++len]=n%10;
55         n/=10;
56     }
57     return dfs(len,0,0,0,true);
58 }
59
60 int main()
61 {
62     //freopen("input.txt","r",stdin);
63     memset(f, -1, sizeof(f));
64     LL L, R;int t;
65     cin>>t;
66     while( t-- )
67     {
68         cin>>L>>R;
69         cout<<cal(R)-cal(L-1)<<endl;
70     }
71     return 0;
72 }
73
74 AC代码

AC代码

时间: 2025-01-15 22:24:49

SPOJ BALNUM Balanced Numbers 平衡数(数位DP,状压)的相关文章

CCF 201312-4 有趣的数 (数位DP, 状压DP, 组合数学+暴力枚举, 推公式, 矩阵快速幂)

问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前. 3. 最高位数字不为0. 因此,符合我们定义的最小的有趣的数是2013.除此以外,4位的有趣的数还有两个:2031和2301. 请计算恰好有n位的有趣的数的个数.由于答案可能非常大,只需要输出答案除以1000000007的余数. 输入格式 输入只有一行,包括恰好一个正整数n (4 ≤ n ≤ 1000). 输

SPOJ BALNUM Balanced Numbers 状压+数位DP

一开始想了一个用二进制状压的方法,发现空间需要的太大,光光memset都要超时 = = 其实不用每次都memset 也可以用三进制,一开始直接打表出所有的状态转移就好 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream&g

HDU 4352 XHXJ&#39;s LIS 数位DP + 状压

由LIS的nlogn解法 可以得出最后统计数组中数的个数即为LIS的长度 这样就可以状压了 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <c

HDU.4352.XHXJ&#39;s LIS(数位DP 状压 LIS)

题目链接 数位DP. 至于怎么求LIS,因为只有10个数,所以可以参照O(nlogn)求LIS的方法,状压记录状态. 每次加一个数和求LIS一样更新状态.最后状态中1的个数就是LIS的长度. //93MS 3004K #include <cstdio> #include <cctype> #include <cstring> #include <algorithm> #define gc() getchar() typedef long long LL; c

SPOJ BALNUM Balanced Numbers(数位dp,状态压缩)

BALNUM - Balanced Numbers no tags 题目链接 Balanced numbers have been used by mathematicians for centuries. A positive integer is considered a balanced number if: 1)      Every even digit appears an odd number of times in its decimal representation 2)   

SPOJ BALNUM Balanced Numbers(数位dp)

Balanced Numbers Time Limit:123MS     Memory Limit:1572864KB     64bit IO Format:%lld & %llu Submit Status Practice SPOJ BALNUM Description Balanced numbers have been used by mathematicians for centuries. A positive integer is considered a balanced n

SPOJ - BALNUM - Balanced Numbers(数位DP)

链接: https://vjudge.net/problem/SPOJ-BALNUM 题意: Balanced numbers have been used by mathematicians for centuries. A positive integer is considered a balanced number if: 1) Every even digit appears an odd number of times in its decimal representation 2)

SPOJ10606 BALNUM - Balanced Numbers(数位DP+状压)

Balanced numbers have been used by mathematicians for centuries. A positive integer is considered a balanced number if: 1)      Every even digit appears an odd number of times in its decimal representation 2)      Every odd digit appears an even numb

【BZOJ1662】[Usaco2006 Nov]Round Numbers 圆环数 数位DP

[BZOJ1662][Usaco2006 Nov]Round Numbers 圆环数 Description 正如你所知,奶牛们没有手指以至于不能玩"石头剪刀布"来任意地决定例如谁先挤奶的顺序.她们甚至也不能通过仍硬币的方式. 所以她们通过"round number"竞赛的方式.第一头牛选取一个整数,小于20亿.第二头牛也这样选取一个整数.如果这两个数都是 "round numbers",那么第一头牛获胜,否则第二头牛获胜. 如果一个正整数N的二