ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

$[SDOI2009]Bill$的挑战

2019-10-26 09:53:44  阅读:273  来源: 互联网

标签:状态 状压 int 挑战 Bill while && SDOI2009


\([SDOI2009]Bill\)的挑战

观察数据范围,显然是状压。

但是如果你将\(K\)加进状态中,手推一下就会发现这里要用到容斥。

但我又不是讲容斥的是吧。。。

所以我们尝试不将\(K\)加入状态中,而是在最后枚举恰好含有\(K\)个元素的子集个数。

我们设\(f[i][j]\)表示对于所有集合\(i\)中的元素,匹配到第\(j\)位时的方案数。

实际上我们涉及到集合的状压转移时如果考虑一个状态由哪里转移来,要枚举合法子集,显然麻烦。

我们可以考虑当前状态可转移到哪里,这样只用造出合法状态即可。

我们同时还要预处理一个\(Mat[i][j]\)表示一个集合,其中的所有元素满足,第\(i\)位可以匹配到字母\(j\)。

有点卡时限,最好不要用\(memset\)。

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    int f=1,w=0;char x=0;
    while(x<'0'||x>'9') {if(x=='-') f=-1; x=getchar();}
    while(x!=EOF&&x>='0'&&x<='9') {w=(w<<3)+(w<<1)+(x^48);x=getchar();}
    return w*f;
}
const int N=17;
const int M=60;
const int p=1e6+3;
char S[N][M];
int n,m,K,ans;
int f[1<<N][M],Mat[M][M];
signed main(){
#ifndef ONLINE_JUDGE
    freopen("A.in","r",stdin);
#endif
    int T=read();
    while(T--)
    {
        n=read(),K=read();
        for(register int i=1;i<=n;i++) scanf("%s",S[i]);
        m=strlen(S[1]);ans=0;
        for(register int i=0;i<m;i++)
            for(register int C=0;C<26;C++)
                for(register int j=1;j<=n;j++)
                    if(S[j][i]=='?'||S[j][i]==C+'a')
                        Mat[i][C]|=(1<<(j-1));
        f[(1<<n)-1][0]=1;
        for(register int i=0;i<m;i++)
            for(register int j=0;j<=(1<<n)-1;j++)
                if(f[j][i]) 
                    for(register int C=0;C<26;C++)
                        f[Mat[i][C]&j][i+1]=(f[Mat[i][C]&j][i+1]+f[j][i])%p;
        for(register int i=0;i<=(1<<n)-1;i++)
        {
            register int Sum=0;
            for(register int j=1;j<=(1<<n)-1;j<<=1) Sum+=(bool)(i&j);
            if(Sum==K) ans=(ans+f[i][m])%p;
        }
        printf("%d\n",ans);
        for(register int i=0;i<=(1<<n);i++)
            for(register int j=0;j<=m;j++) f[i][j]=0;
        for(register int i=0;i<=m;i++)
            for(register int C=0;C<=26;C++) Mat[i][C]=0;
    }
}

标签:状态,状压,int,挑战,Bill,while,&&,SDOI2009
来源: https://www.cnblogs.com/wo-shi-zhen-de-cai/p/11741891.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有