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

Description 

Input

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

1 2 1 a? ?b 
Sample Input

50 
Sample Output

对于30%的数据,T ≤ 5,M ≤ 5,字符串长度≤ 20;

对于70%的数据,T ≤ 5,M ≤ 13,字符串长度≤ 30;

对于100%的数据,T ≤ 5,M ≤ 15,字符串长度≤ 50。

【思路】

状压DP

设f[i][s]表示前i-1个已经匹配,且匹配集合为s时的方案数。预处理出g[i][j]表示长度为i-1且最后一个字符为j的字符串集合。则有转移方程如下:

f[i+1][s&g[i][k]]+=f[i][j]

【代码】

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4
 5 const int N = 16 , M = 55;
 6 const int MOD = 1e6+3;
 7
 8 int f[M][1<<N],g[M][26];
 9 char s[N][M];
10
11 int T,n,K,len;
12
13 int main() {
14     scanf("%d",&T);
15     while(T--) {
16         memset(f,0,sizeof(f));
17         memset(g,0,sizeof(g));
18         scanf("%d%d",&n,&K);
19         for(int i=0;i<n;i++)
20             scanf("%s",s[i]);
21         len=strlen(s[0]);
22         for(int i=0;i<len;i++)
23             for(int j=0;j<n;j++) {
24                 if(s[j][i]!=‘?‘)
25                     g[i][s[j][i]-‘a‘]^=(1<<j);
26                 else
27                     for(int k=0;k<26;k++)
28                         g[i][k]^=(1<<j);
29             }
30         int all=1<<n; f[0][all-1]=1;
31         for(int i=0;i<len;i++)
32             for(int j=0;j<all;j++) if(f[i][j])
33                 for(int k=0;k<26;k++)
34                     f[i+1][j&g[i][k]]=(f[i+1][j&g[i][k]]+f[i][j])%MOD;
35         int ans=0,cnt;
36         for(int j=0;j<all;j++) {
37             cnt=0;
38             for(int i=0;i<n;i++)
39                 if(j&(1<<i)) cnt++;
40             if(cnt==K) ans=(ans+f[len][j])%MOD;
41         }
42         printf("%d\n",ans);
43     }
44     return 0;
45 }
时间: 2024-12-16 20:39:55

bzoj 1879 [Sdoi2009]Bill的挑战(状压DP)的相关文章

BZOJ 1879 [Sdoi2009]Bill的挑战 ——状压DP

本来打算好好写写SDOI的DP题目,但是忒难了, 太难了,就写的这三道题仿佛是可做的. 生在弱省真是兴奋. 这题目直接状压,f[i][j]表示匹配到i,状态集合为j的方案数,然后递推即可. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k

bzoj1879: [Sdoi2009]Bill的挑战 状压dp

题目传送门 https://www.lydsy.com/JudgeOnline/problem.php?id=1879 题解 我们考虑用\(p[i][j]\)存所有字符串的信息,\(i\)表示字符串的第\(i\)个字符,\(j\)表示英文字母\(a-z\),\(p[i][j]\)用二进制存,例如\(p[1][0]=1100\)表示第一位可以为\(a\)的为第一个字符串和第二个字符串. 然后我们按字符串长度\(dp\),\(f[i][j]\)表示方案数,\(i\)表示字符串的第\(i\)个字符,\

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

石乐志写容斥--其实状压dp就行 设f[i][s]表示前i个字母,匹配状态为s,预处理g[i][j]为第i个字母是j的1~n的集合,转移的时候枚举26个字母转移,最后答案加上正好有k个的方案即可 #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int mod=1000003; int T,n,m,len,t,f[55][50005],g[55][27],an

[BZOJ 1072] [SCOI2007] 排列perm 【状压DP】

题目链接:BZOJ 1072 这道题使用 C++ STL 的 next_permutation() 函数直接暴力就可以AC .(使用 Set 判断是否重复) 代码如下: #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <cmath> #include <set>

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

简单的状压dp... dp( x , h , s ) 表示当前第 x 行 , 用了 h 个 king , 当前行的状态为 s . 考虑转移 : dp( x , h , s ) = ∑ dp( x - 1 , h - cnt_1( s ) , s' ) ( s and s' 两行不冲突 , cnt_1( s ) 表示 s 状态用了多少个 king ) 我有各种预处理所以 code 的方程和这有点不一样 ------------------------------------------------

BZOJ 3446: [Usaco2014 Feb]Cow Decathlon( 状压dp )

水状压dp. dp(x, s) = max{ dp( x - 1, s - {h} ) } + 奖励(假如拿到的) (h∈s). 时间复杂度O(n * 2^n) ---------------------------------------------------------------------------------- #include<bits/stdc++.h> #define rep(i, n) for(int i = 0; i < n; ++i) #define clr(x

【BZOJ1226】[SDOI2009]学校食堂Dining 状压DP

[BZOJ1226][SDOI2009]学校食堂Dining Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整数表示.由于人手不够,食堂每次只能为一个人做菜.做每道菜所需的时间是和前一道菜有关的,若前一道菜的对应的口味是a,这一道为b,则做这道菜所需的时间为(a or b)-(a and b),而做第一道菜是不需要计算时间的.其中,o

BZOJ 1076 SCOI2008 奖励关 期望状压DP

题目大意:给定k次弹出宝物的机会,每次随机弹出n种宝物的机会,如果吃过这种宝物的所有前提宝物就可以吃这种宝物,求最优策略的期望得分 看到数据范围果断状压DP- - 不看数据范围害死人- - 至于吃还是不吃 这是个问题 对于这种最优策略的期望DP 我们一般都是从后往前推 枚举每次出现宝物 枚举此时的状态 枚举宝物是哪种 如果当前的宝物可以吃 就在吃与不吃的后继状态中选择最大值加到当前状态上 如果当前的宝物不能吃 只能选择不吃的后继状态加到当前状态上 最后输出f[1][0]就是答案 #include

BZOJ 4197 NOI 2015 寿司晚宴 状压DP

4197: [Noi2015]寿司晚宴 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 694  Solved: 440[Submit][Status][Discuss] Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了 n?1 种不同的寿司,编号 1,2,3,-,n?1,其中第 i 种寿司的美味度为 i+1 (即