关闭

BZOJ1879: [Sdoi2009]Bill的挑战

256人阅读 评论(0) 收藏 举报
分类:

字符串不是很多,可以考虑状态压缩
f[i][j]表示到匹配到第i位,匹配状态为j,j在二进制下就表示和这n个串的匹配情况
然后加个滚动
然而貌似有很多废的状态,直接DP复杂度好像也过不去,于是我就记录了当前这一层有哪些状态


code:

#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

const int maxn = 16;
const int maxl = 60;
const int Mod = 1000003;

int f[2][1<<maxn];
int num[2][1<<maxn];
char st[maxn][maxl];
int n,m;

int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%s",st[i]);
        int len = strlen(st[1]);

        int now=1;
        memset(f[now],0,sizeof f[now]);
        memset(num[now],0,sizeof num[now]);
        f[now][(1<<n)-1]=1; num[now][0]=1; num[now][1]=(1<<n)-1;
        for(int i=0;i<len;i++)
        {
            now^=1;
            memset(f[now],0,sizeof f[now]);
            memset(num[now],0,sizeof num[now]);
            for(int j=1;j<=num[1^now][0];j++)
            {
                int ki=num[1^now][j];
                for(int l=0;l<26;l++)
                {
                    int ti=0,ni=0;
                    for(int k=1;k<=n;k++)
                    if(((1<<k-1)&ki)&&(st[k][i]=='?'||st[k][i]-'a'==l))
                        ni++,ti|=(1<<k-1);
                    if(ni>=m)
                    {
                        if(!f[now][ti])
                        {
                            num[now][0]++;
                            num[now][num[now][0]]=ti;
                            f[now][ti]=f[1^now][ki];
                        }
                        else
                        {
                            f[now][ti]+=f[1^now][ki];
                            f[now][ti]=(f[now][ti]-1)%Mod+1;
                        }
                    }
                }
            }
        }
        int r=0;
        for(int i=0;i<1<<n;i++)
        {
            int ni=0;
            for(int j=1;j<=n;j++) if(i&(1<<j-1)) ni++;
            if(ni==m) (r+=f[now][i])%=Mod;
        }
        printf("%d\n",r);
    }

    return 0;
}
0
0
查看评论

【bzoj1879】【SDOI2009】【bill的挑战】【状压dp】

Description Input 本题包含多组数据。 第一行:一个整数T,表示数据的个数。 对于每组数据: 第一行:两个整数,N和K(含义如题目表述)。 接下来N行:每行一个字符串。 Output  1   2 1  a?...
  • sunshinezff
  • sunshinezff
  • 2016-03-31 18:43
  • 514

【SDOI2009】【BZOJ1879】Bill的挑战

Description Input本题包含多组数据。 第一行:一个整数T,表示数据的个数。 对于每组数据: 第一行:两个整数,N和K(含义如题目表述)。 接下来N行:每行一个字符串。 Output1 2 1 a? ?b Sample Input50 Sample Output对于30%的数据...
  • CreationAugust
  • CreationAugust
  • 2016-02-20 14:35
  • 836

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

状压DP。定义状态f[i][S]" role="presentation" style="position: relative;">f[i][S]f[i][S]f[i][S]表示前i" role="presentation&...
  • xyz32768
  • xyz32768
  • 2018-01-31 13:57
  • 26

【50.54%】【BZOJ 1879】[Sdoi2009]Bill的挑战

Time Limit: 4 Sec  Memory Limit: 64 MB Submit: 649  Solved: 328 [Submit][Status][Discuss] Description ...
  • harlow_cheng
  • harlow_cheng
  • 2016-09-23 19:10
  • 183

bzoj 1879 [Sdoi2009]Bill的挑战

题意 自己戳好伐?权限+图片,好吧我懒很好的状压dp 按说 看到题目的数据范围就应该确定是 状压dp 但是 我想了想 觉得没法搞啊果断 弃疗然后 探究样例发现神奇啊如果把每一位 可以填的 字符 个数确定就好了 比如eg的25+25 遂发现 不是很好搞。然后 转化成了 枚举每一位上放哪个字...
  • mars_ch
  • mars_ch
  • 2016-11-14 10:41
  • 114

BZOJ 1879 [Sdoi2009] Bill的挑战

状压DP
  • SenyeLicone
  • SenyeLicone
  • 2017-02-28 12:20
  • 262

1879: [Sdoi2009]Bill的挑战 状压DP

还是状压DP。 考虑用fi,jf_{i,j}表示当前枚举到第ii位,匹配状态为jj的方案数。 枚举2626个字母,求出当前位放每个字母的匹配状态tmptmp,然后转移: fi,j and tmp+=fi−1,jf_{i,j \ and \ tmp}+=f_{i-1,j}然后...
  • Phenix_2015
  • Phenix_2015
  • 2016-02-26 11:03
  • 319

【BZOJ 1876】 [SDOI2009]SuperGCD

更相减损术+高精度/python~
  • Regina8023
  • Regina8023
  • 2015-04-19 09:03
  • 1657

Bill的挑战(set)

Bill的挑战 问题描述: Sheng bill 不仅有惊人的心算能力,还可以轻松地完成各种统计。在昨天的比赛中,你 凭借优秀的程序与他打成了平局,这导致Sheng bill 极度的不满。于是他再次挑战你。这次 你可不能输! 这次,比赛规则是这样的: 给N 个长度相同的字符串(由小写英文...
  • weixinding
  • weixinding
  • 2012-02-13 06:57
  • 304

[bzoj 1879] [Sdoi2009]Bill的挑战:状压DP,自创数学公式(?)

题意:给N个(1<=N<=15)含小写字母、?的长度不超过50的等长字符串,求有多少个含小写字母的字符串和恰好K个串匹配。?可匹配任意字符。 我写了个奇怪的状压DP并发现一个计算恰在n个集合中出现k次的元素数目的数学公式...... 人生第一次发明数学公式(?),不过不会证......
  • ruoruo_cheng
  • ruoruo_cheng
  • 2016-11-06 20:06
  • 301
    个人资料
    • 访问:132589次
    • 积分:5608
    • 等级:
    • 排名:第5601名
    • 原创:443篇
    • 转载:0篇
    • 译文:0篇
    • 评论:18条