[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. BigDecimal的setScale()方法无效(坑)

    最近在使用BigDecimal进行四舍五入时,发现setScale()方法设置的精度值并没有起作用,一度让我怀疑起是否jdk有bug,代码如下: 错误代码 double d = 7.199999999 ...

  2. 20135220谈愈敏Linux Book_1&2

    第一章 Linux内核简介 从unix的历史视角来认识Linux内核与Linux操作系统的前世今生. Unix历史 贝尔实验室设计的一个文件系统原型逐渐演化而成Unix,而后Unix操作系统用C语言重 ...

  3. javascript 函数的几种声明函数以及应用环境

    本页只列出常用的几种方式,当然还有比如new Function()以及下面三种的组合. 1.函数式声明 例子:function sum(a,b){ return a+b; }; 2.函数表达式声明(匿 ...

  4. OpenState: Programming Platform-independent Stateful OpenFlow Applications Inside the Switch

    文章名称:OpenState: Programming Platform-independent Stateful OpenFlow Applications Inside the Switch Op ...

  5. 对常用软件的评价(TGP腾讯游戏平台)

    1,首先说下界面,这款软件的界面有些类似于QQ的界面,登录方式和QQ的方式是一样的,可以简单的说是一款给游戏用的QQ,就是里面的用户变成了游戏 2,功能,简单的说就是将你常玩的游戏放于这游戏平台的表面 ...

  6. DirectoryEntry_Properties属性的遍历(win2003)

    DirectoryEntry root = new DirectoryEntry(@"IIS://localhost/W3SVC"); string PInfo = "& ...

  7. TestNG简单介绍以及安装—学习笔记1

    TestNG是什么 到这里,大家肯定已经运行了一些关于Selenium的测试用例了(这里主要是站着一个自动化测试工程师的角度来看待TestNG的,所以这里所说的也都是基于Web测试的验证点来说的,而不 ...

  8. Python 实现数据库更新脚本的生成

    我在工作的时候,在测试环境下使用的数据库跟生产环境的数据库不一致,当我们的测试环境下的数据库完成测试准备更新到生产环境上的数据库时候,需要准备更新脚本,真是一不小心没记下来就会忘了改了哪里,哪里添加了 ...

  9. 随web应用启动而自启动的后台线程

    当前遇到一个需求: 需要在web应用启动的时候就启动一个线程定时的来做某项工作. 有两种解决方法: 1.增加一个监听器Listener来实现相关功能. 2.增加一个随项目启动的servlet来实现相关 ...

  10. DBA 这个角色

    下面这些领域的技能可以提升DBA团队对公司业务产生正面影响的重要能力: ---------------------------------------------------------------- ...