SPOJ BALNUM ★(位压缩状态+数位DP)
题意
求区间[A,B]上的平衡数个数。平衡数是这样的数:在数的各个位上,奇数数字出现偶数次,偶数数字出现奇数次。
思路
很明显我们需要记录每一位出现的次数。分别记录是不明智的,而我们又只需要记录奇数次或者偶数次即可。所以我们可以用一个<=1024的数state表示0~9这10个数字出现的次数奇偶性,当奇数出现偶数次则相应位为1,当偶数出现奇数次相应位为1,最后判断是不是1023。但是这样它的初试状态不好确定。很明显初始时我们需要把state赋值成1010101010,即682(0次算偶次)。但是如果某些偶数位从始至终都没有出现,那么那一位最终为0显然不合理。我也没有想到什么更好的办法,只能再加一个1024的vis数表示0~9这10个数字是否出现过,但这样空间不够。后来想到一个优化是我们不必记录奇数是否出现过,因为它们初始就为1。所以可以把vis缩减到32,这样空间就足够了~问题边迎刃而解。
代码
[cpp]
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#define MID(x,y) ((x+y)/2)
#define MEM(a,b) memset(a,b,sizeof(a))
#define REP(i, begin, m) for (int i = begin; i < begin+m; i ++)
using namespace std;
typedef long long LL;
typedef vector <int> VI;
typedef set <int> SETI;
typedef queue <int> QI;
typedef stack <int> SI;
LL dp[20][1050][35][2];
VI num;
LL dfs(int pos, int state, int vis, bool flag, bool limit){
if (pos == -1){
bool ok = 1;
for (int i = 0; i <= 9; i ++)
if ((state & (1<<i)) == 0){
if (i % 2) {ok = 0; break;}
else if ((vis & (1 << (i/2))) != 0){
ok = 0; break;
}
}
return ok;
}
if (!limit && ~dp[pos][state][vis][flag]) return dp[pos][state][vis][flag];
int end = limit?num[pos]:9;
LL res = 0;
for (int i = 0; i <= end; i ++){
int next_state, next_vis;
if (i == 0 && !flag){
if (pos == 0){
next_state = state | 1;
next_vis = vis|1;
}
else{
next_state = state;
next_vis = vis;
}
}
else{
next_state = state ^ (1<<i);
if (i % 2 == 0)
next_vis = vis|(1<<(i/2));
else
next_vis = vis;
}
res += dfs(pos-1, next_state, next_vis, (!flag)&&i==0?flag:true, limit && (i==end));
}
return limit?res:dp[pos][state][vis][flag] = res;
}
LL cal(LL x){
num.clear();
while(x){
num.push_back(x%10);
x /= 10;
}
int len = num.size();
return dfs(len-1, 682, 0, 0, 1);
}
int main(){
//freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
MEM(dp, -1);
int t;
scanf("%d", &t);
while(t --){
LL a, b;
scanf("%lld %lld", &a, &b);
printf("%lld\n", cal(b)-cal(a-1));
}
// for (int i = 100; i <= 1000; i ++){
// if (cal(i)-cal(i-1) == 1)
// printf("i = %d\n", i);
// }
return 0;
}
[/cpp]
SPOJ BALNUM ★(位压缩状态+数位DP)的更多相关文章
- SPOJ BALNUM Balanced Numbers (数位dp)
题目:http://www.spoj.com/problems/BALNUM/en/ 题意:找出区间[A, B]内所有奇数字出现次数为偶数,偶数字出现次数为计数的数的个数. 分析: 明显的数位dp题, ...
- SPOJ BALNUM Balanced Numbers(数位DP+状态压缩)题解
思路: 把0~9的状态用3进制表示,数据量3^10 代码: #include<cstdio> #include<map> #include<set> #includ ...
- SPOJ - BALNUM Balanced Numbers(数位dp+三进制状压)
Balanced Numbers Balanced numbers have been used by mathematicians for centuries. A positive integer ...
- SPOJ - BALNUM - Balanced Numbers(数位DP)
链接: https://vjudge.net/problem/SPOJ-BALNUM 题意: Balanced numbers have been used by mathematicians for ...
- BALNUM - Balanced Numbers(数位dp)
题目链接:http://www.spoj.com/problems/BALNUM/en/ 题意:问你在[A,B]的闭区间内有几个满足要求的数,要求为每个出现的奇数个数为偶数个,每个出现的偶数个数为奇数 ...
- 数位dp备忘录
hdu 4734:把限制值化为数组形式,逐位求解 hdu 4507:类似于上题,其中求平方和的方法很妙 SPOJ BALNUM Balanced Numbers:经典数位dp,注意两点,1,不要把前 ...
- 【SPOJ 1182】 SORTBIT - Sorted bit squence (数位DP)
SORTBIT - Sorted bit squence no tags Let's consider the 32 bit representation of all integers i from ...
- [kuangbin带你飞]专题十五 数位DP
ID Origin Title 62 / 175 Problem A CodeForces 55D Beautiful numbers 30 / 84 Problem B HD ...
- Luogu3220 HNOI2012 与非 数位DP
传送门 题意:给出$N$个范围在$[0,2^k-1]$的整数,定义位运算$NAND$为位运算$AND$的逆运算,求$[L,R]$中有多少数能成为若干个前面给出的整数.若干括号和$NAND$运算组成的表 ...
随机推荐
- pycharm激活(转)
1.注册码激活Activation code http://idea.lanyus.com/ 2.服务器激活License server(推荐) 或者http://182.254.242.193:10 ...
- BigInteger和Complex:NET 4新增数据类型
BigInteger和Complex是.NET 4中新增的两种值类型,他们位于System.Numeric命名空间下,需要单独添加引用. BigInteger BigInteger类型是不可变类型,代 ...
- Oblect类之hashCode和equals
1.hashCode的默认实现.显然是一个本地方法. 2.equals的默认实现.默认equals在比较两个对象时,是看他们是否指向同一个地址的.“==”操作比较的是两个变量的值是否相等,对于引用型变 ...
- spoj8222
地址: 题目: NSUBSTR - Substrings no tags You are given a string S which consists of 250000 lowercase la ...
- Jmeter数据库mysql测试说明
主要分3个步骤,详细操作步骤如下: 一.环境准备 1.下载mysql驱动,下载地址:https://dev.mysql.com/downloads/connector/j/,Select Operat ...
- iOS开发之NSUserDefaults
在ios中偏好设置保存用户配置的对象 //NSUserDefaults读取 //获取标准函数对象 //通过对象获取名称下NSMutableDictionary数据 NSUserDefaults *de ...
- cx_Oracle连接数据库总结
python中连接oracle数据库使用第三方库文件cx_Oracle时遇到了各种问题,网上查找资料调试了几天才弄好,下面是不断调试后总结的一些经验.1.oracle客户端(Oracle Instan ...
- 《Java入门第三季》第二章 认识 Java 中的字符串
什么是 Java 中的字符串.1.在Java的世界里,字符串被作为String类型的对象处理. 2.通用的初始化的方式:String s = new String("i love you & ...
- 编码解码--url编码解码
url编码解码,又叫百分号编码,是统一资源定位(URL)编码方式.URL地址(常说网址)规定了常用地数字,字母可以直接使用,另外一批作为特殊用户字符也可以直接用(/,:@等),剩下的其它所有字符必须通 ...
- python计算纪念日相关
注意需要python3 1.距离某一特定日期多少天后,如 100天 from datetime import datetime,timedelta pre=datetime(2016,12,12,22 ...