[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. 了不起的Node.js--之二

    安装模块 使用NPM包管理器可以让你轻松对模块进行管理,它会下载指定的包.解决包的依赖.进行测试脚本及安装命令行脚本. 安装二进制工具包 有的项目分发的是Node编写的命令行工具.这个时候,安装时要增 ...

  2. 《Linux内核分析》第二周笔记 操作系统是如何工作的

    操作系统是如何工作的 一.函数调用堆栈 1.三个法宝 计算机是如何工作的?(总结)——三个法宝(存储程序计算机.函数调用堆栈.中断机制) 1)存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: ...

  3. 读书笔记(chapter5)

    系统调用 5.1与内核通信 1.系统调用在用户空间进程和硬件设备之间添加一个中间层.作用有三个:它为用户空间提供了一种硬件的抽象接口:系统调用保证了系统的稳定和安全:系统调用是用户空间访问内核的唯一手 ...

  4. 第二阶段Sprint7

    昨天:将“录制”及“保存”整合到一起,修复出现的Bug,使之能够正常运行. 今天:把视频录制整合到时间提醒里,实现视频提醒 遇到的问题:额,整进去直接就停止运行了..也没有报错..

  5. [BUG随想录] 看不见的分隔符: Zero-width space

    今天在调试一段代码的时候,有一个输入不能为空的库函数抛出了异常(为空就会抛出异常,就是这么傲娇).自己暗骂了自己一番,怎么这么大意,于是追溯源头,开始寻找输入控制的地方.但是当我找到时我惊呆了,我明明 ...

  6. win10下装上virtualbox 以及在virtualbox上装上 ubuntu 12.04

    首先要下载virtual 在win10下可能第一步你就遇到了麻烦 首先刚开始我装的是最新版本的virtualbox 5.0.24.8355 (直接百度就可搜到) 然后可以按照这个教程 http://j ...

  7. 浅谈个人对存储区域网络SAN的理解

    存储区域网络SAN,是一种通过将网络存储设备和服务器连接起来的网络,提供计算机和存储设备间的数据传输.其中,SAN是独立于服务器系统之外的,拥有近乎无限的存储能力,通过利用光纤作为传输媒介,实现了高速 ...

  8. Windows 设置开机自动登录

    1. 自己一些windows的虚拟机 有时候开机之后 输入用户名密码时间特别长. 需要等待很久, 如果能够设置开机自动登录的话 能够节约很多时间. 2. 最简单的办法  运行输入 control us ...

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

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

  10. Yii 框架的Rbac [权限控制]

    转载自 xmlife 的博客 : http://blog.csdn.net/xmlife/article/details/50733451 1.首先我们要在配置文件的组件(component)里面配置 ...