[BZOJ 1879][SDOI 2009]Bill的挑战

Description

Solution

1.考虑状压的方式。

方案1:如果我们把每一个字符串压起来,用一个布尔数组表示与每一个字母的匹配关系,那么空间为26^50,爆内存;

方案2:把每一个串压起来,多开一维记录匹配字符,那么空间为nlen26,合法,但不便于状态的设计和转移;

方案3:把每一个串同一个位置的字符放在一起,用一个布尔数组记录与每一个小写字母的匹配关系,那么空间为26^15*len,爆内存;

方案4:把每一个串同一个位置的字符压起来,用多开一维的整形数组记录与每一个小写字母的匹配关系,空间为2^15*len,合法;

采用方案4,那么关系具体的记录方式就是,开一个压缩数组r[2^15][len],r[i][j]表示所有串第i位与第j个小写字母的匹配情况:

例如,第1到n个串的第i位分别为:?,a, b,c,那么他们与'a'的匹配情况为r[i][0]=0011;

void init(){
for(R int i=0;i<len;++i)//第i列
for(R int x=0;x<26;++x){//对'a'增量为x
r[i][x]=0;
for(R int k=0;k<n;++k)//第k个串
if(s[k][i]=='?'||s[k][i]=='a'+x)r[i][x]|=(1<<k);
}
}

2.考虑DP的过程

方案1:f[i][j]表示当前匹配长度位i,状态为j,实际上也就是符合要求的匹配情况为j时的方案数

方案2:f[i][j]表示当前匹配到第i位,状态为j时的方案数;

两种方案均可,只是第一种的i永远比第二种的i多1罢了。

但是我们要采用方案1,因为初始化时,未匹配情况应该只有一个那就是111...111,所以对于第一种情况初始化就非常简单,也就是f[0][(1<<n)-1]=1;

然后就是转移,我们发现当且仅当前一位时当前状态合法才可转移,我们转移采用扩展状态的方式,即在当前状态上枚举增加状态,所以状态转移方程是:

(f[i][j&r[i-1][x]]+=f[i-1][j])%=mod;

Code

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define R register
typedef long long ll;
using namespace std; const int mod=1e6+3; string s[20];
int n,m,r[51][50010],f[51][50010]; inline int lowbit(int x){return x&-x;} void init(){
cin>>n>>m;
memset(f,0,sizeof(f));
for(R int i=0;i<n;++i)cin>>s[i];
int len=s[0].size();
for(R int i=0;i<len;++i)//第i列
for(R int x=0;x<26;++x){//对'a'增量为x
r[i][x]=0;
for(R int k=0;k<n;++k)//第k个串
if(s[k][i]=='?'||s[k][i]=='a'+x)r[i][x]|=(1<<k);
}
} void work(){
int lim=(1<<n)-1;
int len=s[0].size();
f[0][lim]=1;
for(R int i=1;i<=len;++i)
for(R int j=0;j<=lim;++j)//状态
if(f[i-1][j])//如果当前前一列子集被更新过,即要扩展的状态合法
for(R int x=0;x<26;++x)//对'a'增量为x
(f[i][j&r[i-1][x]]+=f[i-1][j])%=mod;
int ans=0;
for(R int i=0;i<=lim;++i){
int temp=i,cnt=0;
while(temp){cnt++;temp-=lowbit(temp);}
if(cnt==m) (ans+=f[len][i])%=mod;
}
printf("%d\n",ans);
}
int main(){
ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--){
init();
work();
}
return 0;
}

[BZOJ 1879][SDOI 2009]Bill的挑战 题解(状压DP)的更多相关文章

  1. BZOJ1879 [Sdoi2009]Bill的挑战 【状压dp】

    题目 输入格式 本题包含多组数据. 第一行:一个整数T,表示数据的个数. 对于每组数据: 第一行:两个整数,N和K(含义如题目表述). 接下来N行:每行一个字符串. T ≤ 5,M ≤ 15,字符串长 ...

  2. bzoj 1879 [Sdoi2009]Bill的挑战(状压DP)

    Description  Input 本题包含多组数据. 第一行:一个整数T,表示数据的个数. 对于每组数据: 第一行:两个整数,N和K(含义如题目表述). 接下来N行:每行一个字符串. Output ...

  3. bzoj 1879: [Sdoi2009]Bill的挑战【状压dp】

    石乐志写容斥--其实状压dp就行 设f[i][s]表示前i个字母,匹配状态为s,预处理g[i][j]为第i个字母是j的1~n的集合,转移的时候枚举26个字母转移,最后答案加上正好有k个的方案即可 #i ...

  4. BZOJ 1688: [Usaco2005 Open]Disease Manangement 疾病管理 状压DP + 二进制 + 骚操作

    #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) #defin ...

  5. 「BZOJ 5161」最长上升子序列「状压DP」

    题意 求一个\(1\sim n\)的排列LIS的期望长度,\(n\leq 28\) 题解 考虑朴素的LIS:\(f[i] = min(f[j]) + 1\) 记\(mx[i]\)为\(f\)的前缀最大 ...

  6. 【50.54%】【BZOJ 1879】[Sdoi2009]Bill的挑战

    Time Limit: 4 Sec  Memory Limit: 64 MB Submit: 649  Solved: 328 [Submit][Status][Discuss] Descriptio ...

  7. 【BZOJ】1087: [SCOI2005]互不侵犯King(状压dp)

    http://www.lydsy.com:808/JudgeOnline/problem.php?id=1087 状压dp是第一次写啊,我也是才学TAT.状压dp一般都用一个值表示集合作为dp的一个状 ...

  8. BZOJ 1097: [POI2007]旅游景点atr( 最短路 + 状压dp )

    先最短路预处理, 然后状压就行了 -------------------------------------------------------------------------- #include ...

  9. 【BZOJ 2595】2595: [Wc2008]游览计划 (状压DP+spfa,斯坦纳树?)

    2595: [Wc2008]游览计划 Time Limit: 10 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 1572  Solved: 7 ...

随机推荐

  1. Async 异步转同步详细流程解释

      安装 npm install async --save 地址 https://github.com/caolan/async Async的内容主要分为三部分 流程控制: 简化九种常见的流程的处理 ...

  2. 1086. Tree Traversals Again (25)-树的遍历

    题意:用栈的push.pop操作给出一棵二叉树的中序遍历顺序,求这棵二叉树的后序遍历. 需要一个堆结构s,一个child变量(表示该节点是其父亲节点的左孩子还是右孩子),父亲节点fa对于push v操 ...

  3. mybatis mapper使用记录

    insert://插入一条数据//支持Oracle序列,UUID,类似Mysql的INDENTITY自动增长(自动回写)//优先使用传入的参数值,参数值空时,才会使用序列.UUID,自动增长int i ...

  4. C++ 派生类构造函数和析构函数

    几个问题 一个类的各数据成员的构造顺序? 按他们在类定义中出现的先后顺序:先定义者先构造. 类的对象成员的构造函数与类自身的构造函数的执行顺序? 先执行对象成员的构造函数,再执行类自身的构造函数. 构 ...

  5. Linux内核分析课程期中总结

    Linux内核分析课程期中总结 姓名:王朝宪 学号:20135114 注: 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com ...

  6. Team Work Ⅱ

    Regal-Lighting团队设计 分工思考 本次大作业我的分工定位是:Unit及子类,主要设计实现建筑类的功能. 首先王者光耀这款游戏所需要的建筑分为三类: 1.防御塔:有一定的血量,血量为0时破 ...

  7. Error:java: 无效的源发行版: 1.8

    出现这种情况是gradle或者maven的版本与 本地电脑jdk不一致,具体看一下链接 http://blog.csdn.net/leixingbang1989/article/details/519 ...

  8. WPF使用路径(URI)引用资源文件

    Uri uri = new Uri("pack://application:,,,/程序集名称;component/Resources/bj.png", UriKind.Absol ...

  9. 课堂final发布

    项目组名:奋斗吧兄弟 小组成员:黄兴.李俞寰.栾骄阳.王东涵.杜桥 今天6个小组在课上进行了Final发布,以下是我的一些看法: 1.Nice团队的约跑app: 今天Nice团队给我的最突出的印象就是 ...

  10. [转帖]ESXi 网卡绑定 增加吞吐量的方法

    VMware ESX 5.0 网卡负载均衡配置3种方法 http://blog.chinaunix.net/uid-186064-id-3984942.html (1) 基于端口的负载均衡 (Rout ...