首页 > 其他分享 >【题解】P2167 [SDOI2009]Bill的挑战(状压 DP)

【题解】P2167 [SDOI2009]Bill的挑战(状压 DP)

时间:2022-09-30 15:44:05浏览次数:87  
标签:le sta Bill int 题解 P2167 ch 字符串 dp

【题解】P2167 [SDOI2009]Bill的挑战

挺好的一道状压 DP。可惜我脑子有病。()

题目链接

P2167 [SDOI2009]Bill的挑战

](https://www.luogu.com.cn/problem/P3225)

题意概述

给出 \(N\) 个长度相同的字符串(由小写英文字母和 ? 组成),\(S_1,S_2,\dots,S_N\),求与这 \(N\) 个串中的刚好 \(K\) 个串匹配的字符串 \(T\) 的个数,答案对 \(1000003\) 取模。

若字符串 \(S_x(1\le x\le N)\) 和 \(T\) 匹配,满足以下条件:
\1. \(|S_x|=|T|\)。
\2. 对于任意的 \(1\le i\le|S_x|\),满足 \(S_x[i]= \texttt{?}\) 或者 \(S_x[i]=T[i]\)。

其中 \(T\) 只包含小写英文字母。

数据范围

  • 对于 \(30\%\) 的数据,\(N\le5\),\(|S_i|\le20\);
  • 对于 \(70\%\) 的数据,\(N\le13\),\(|S_i|\le30\);
  • 对于 \(100\%\) 的数据,\(1\le T\le 5\),\(1\le N \le15\),\(1\le|S_i|\le50\)。

思路分析

首先看到这个数据范围肯定想到的是状压,并且要状压的是选了哪些字符串。

那么定义 \(dp_{sta}\) 表示选择 \(sta\) 这个状态的字符串的方案数是多少。

然后就会发现不太好转移,因为我们只能确定 \(sta\) 这个状态构成的字符串对应的方案数是多少,而对于不同的 \(sta\),可能会有相同的一个字符串 \(T\) 满足条件,会算重。

那么我们考虑在状态中加入一维:定义 \(dp_{i,sta}\) 表示考虑到了字符串的第 \(i\) 位,当前选的状态是 \(sta\) 时,方案数是多少。

考虑如何转移。

我们考虑对于一个状态 \(dp_{i,sta}\) 它能转移到哪儿去。

首先肯定是要转移到某一个 \(dp_{i+1,nxt}\) 上去。那么 \(nxt\) 是什么呢。

这时候我们要用到一个辅助数组。

定义 \(f_{i,j}\) 表示的是考虑到了字符串的第 \(i\) 位,这一位上可以与 \(j\) 对应字符匹配的 \(S\) 有哪些。

考虑对于一个 \(j\),这一位上是什么的时候可以与它匹配,比较显然的是要么这一位是 ? 要么是 \(j\) 对应的字符。

那么可以直接枚举 \(i,j\) 并枚举每一个字符串直接判断这一位是否与 \(j\) 匹配即可,可以预处理。

有了这个 \(f\) 数组,我们也就可以轻松的转移 \(dp\) 了。

我们直接考虑下一位填每一个字符 az 时对应的方案数是多少即可。

\[dp[i+1][sta~ \mathrm and~ f[i+1][ch]]+=dp[i][j] \]

初始状态:\(dp_{i,(1<<n)-1}=1\)。

那么最后的答案就是对于每一个状态 \(sta\) 二进制下 \(1\) 的个数恰好为 \(k\) 的所有的 \(dp_{len,sta}\) 之和。其中 \(len\)表示每一个字符串的长度。

代码实现

//luoguP2167
#include<cstdio>
#include<iostream>
#include<cstring>
#define int long long
using namespace std;
const int mod=1000003;
const int maxn=16;
const int maxm=55;
string s[maxn];
int f[maxm][maxm],dp[maxm][1<<maxn],val[1<<maxn];

inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}

signed main()
{
	int T=read();
	while(T--)
	{
		memset(dp,0,sizeof(dp));
		memset(f,0,sizeof(f));
		memset(val,0,sizeof(val));
		int n,k;
		n=read();k=read();
		for(int i=0;i<n;i++)cin>>s[i],s[i]='%'+s[i];
		int len=s[0].size()-1;
		for(int sta=0;sta<(1<<n);sta++)
		{
			for(int i=0;i<n;i++)
			{
				if(sta&(1<<i))val[sta]++;
			}
		}
		for(int i=1;i<=len;i++)
		{
			for(char ch='a';ch<='z';ch++)
			{
				for(int j=0;j<n;j++)
				{
					if(s[j][i]=='?'||s[j][i]==ch)f[i][ch-'a']|=(1<<j);
				}
			}
		}
		dp[0][(1<<n)-1]=1;
		for(int i=0;i<len;i++)
		{
			for(int sta=0;sta<(1<<n);sta++)
			{
				if(!dp[i][sta])continue;
				for(char ch='a';ch<='z';ch++)
				{
					(dp[i+1][sta&f[i+1][ch-'a']]+=dp[i][sta])%=mod;
				}
			}
		}
		int ans=0;
		for(int sta=0;sta<(1<<n);sta++)
		{
			if(val[sta]==k)(ans+=dp[len][sta])%=mod;
		}
		cout<<ans<<'\n';
	}
	return 0;
}

标签:le,sta,Bill,int,题解,P2167,ch,字符串,dp
From: https://www.cnblogs.com/xrkforces/p/luogu-P2167.html

相关文章

  • 13.56M系列芯片-SI522/SI522A/SI523/ FMI7522 /FMI7550 /RC522芯片常见问题解答
    13.56M系列芯片-标配版:SI522/SI522A/SI523的几款芯片会遇到的一些常见问题解答:SI522和SI522A的异同点?SI522A为SI522的升级版本,SI522A增加了ACD工作模式,其他均相同。标配......
  • LG4381 [IOI2008] Island 题解
    LG4381[IOI2008]Island给定一个基环树森林,求每棵基环树的直径长度和。直径是基环树上最长的一条简单路径。题目保证树边的方向构成了一颗内向树。题解先简单说一下......
  • -bash: ./start.sh: /bin/bash^M: bad interpreter问题解决
    出现上面错误的原因是脚本文件是DOS格式,即每一行的行尾以\r\n来标识,使用vim打开脚本,运行::setff?显示fileformat=dos,就是说格式不兼容,在Unix下运行脚本会提示该错误。......
  • 关于multi-statement not allow问题解决
    出现这个问题是因为druid有一个防火墙,默认是不允许批量操作的,目的应该是防止sql注入等风险。如果你在url中设置了allowMultiQueries=true允许批量操作。那么你的配置应该......
  • Redis(六)应用问题解决
    第一章缓存穿透1.1问题描述key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会压到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用......
  • mac zsh: command not found: adb 问题解决
     问题:mac终端提示:zsh:commandnotfound:adb 第一步查看~/.bash_profile的配置是否配置得了AndroidSDK执行命令open ~/.bash_profile  可见存在该配置第二步执行......
  • 洛谷P8551 Bassline 题解
    P8551Bassline题解分析这道题做月赛的时候想了好久,最后发现其实很简单。我们用样例数据来分析:如图所示,我们将每个区间抽象化为一个一个的长条。题目给我们的两个要......
  • 牛客考试7605T2 牛牛的猜球游戏 题解
    2020牛客杯NOIP赛前集训提高第一场T2牛牛的猜球游戏题解目录2020牛客杯NOIP赛前集训提高第一场T2牛牛的猜球游戏题解比赛链接题目题目描述输入格式输出格式样例样例......
  • 洛谷 P7861 SAVEZ 题解(哈希)
    2020牛客杯NOIP赛前集训提高第一场T2牛牛的猜球游戏题解目录2020牛客杯NOIP赛前集训提高第一场T2牛牛的猜球游戏题解比赛链接题目题目描述输入格式输出格式样例样例......
  • 题解【CF1632E1 Distance Tree (easy version)】
    CF1632E1DistanceTree(easyversion&hardversion)解题报告。不一定更好的阅读体验。E2没有地方交了所以就交到E1了。震撼挺大的一道题,钦定\(1\)为根。先......