zoukankan      html  css  js  c++  java
  • [BZOJ1879][SDOI2009]Bill的挑战

    题目描述

    img

    Input

    本题包含多组数据。

    第一行:一个整数(T),表示数据的个数。

    对于每组数据:

    第一行:两个整数,(N)(K)(含义如题目表述)。

    接下来(N)行:每行一个字符串。

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

    Output

    若存在输出(YES),否则输出(NO)

    Sample Input

    5
    3 3
    ???r???
    ???????
    ???????
    3 4
    ???????
    ?????a?
    ???????
    3 3
    ???????
    ?a??j??
    ????aa?
    3 2
    a??????
    ???????
    ???????
    3 2
    ???????
    ???a???
    ????a??
    

    Sample Output

    914852
    0
    0
    871234
    67018
    

    其实看到那么小的数据范围那解题方法也就只有状压或者容斥了。

    鉴于网上状压的题解过多,我们来介绍一下容斥的写法。

    很显然,我们对于一个状态我们要求出有多少种符合条件的串。

    怎么写呢?


    对于当前状态(i),长度为(len),我们逐位考虑,对于当前为(j)

    对于每个在当前状态的串。

    1.若出现有两个串的(Sx[j]!=?,Sy[j]!=?,Sx[j]!=Sy[j])则说明不存在符合条件的串。

    2.若出现该位上所有串都为(?),即对于所有(kin i)都有(S_k[j]=?),则该位上随便选,则方案数乘(26)

    3.否则总方案数不变。


    然后,我们发现若直接这样写,会出现重复的一部分我们没减掉。

    就是会出现一个串在状态(i)可行,但在状态(j)也可行,所以我们要减掉。

    我们倒着枚举状态,对于当前(i)(i)的子集必定会包含(i)的可行状态,所以我们只用把(i)的子集减去(i)的方案数即可。

    最后,我们把所有刚好有(k)(1)的状态的(dp)累加到答案上即可。

    #include <bits/stdc++.h>
     
    using namespace std;
     
    #define int long long
    #define reg register
    #define clr(a,b) memset(a,b,sizeof a)
    #define Mod(x) (x>=mod)&&(x-=mod)
    #define abs(a) ((a)<0?-(a):(a))
    #define debug(x) cerr<<#x<<"="<<x<<endl;
    #define debug2(x,y) cerr<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl;
    #define debug3(x,y,z) cerr<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl;
    #define rep(a,b,c) for(reg int a=(b),a##_end_=(c); a<=a##_end_; ++a)
    #define ret(a,b,c) for(reg int a=(b),a##_end_=(c); a<a##_end_; ++a)
    #define drep(a,b,c) for(reg int a=(b),a##_end_=(c); a>=a##_end_; --a)
    #define erep(i,G,x) for(int i=(G).Head[x]; i; i=(G).Nxt[i])
    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize(3,"Ofast","inline")
     
    inline int Read(void) {
        int res = 0, f = 1;
        char c;
        while (c = getchar(), c < 48 || c > 57)if (c == '-')f = 0;
        do res = (res << 3) + (res << 1) + (c ^ 48);
        while (c = getchar(), c >= 48 && c <= 57);
        return f ? res : -res;
    }
     
    template<class T>inline bool Min(T &a, T const&b) {return a > b ? a = b, 1 : 0;}
    template<class T>inline bool Max(T &a, T const&b) {return a < b ? a = b, 1 : 0;}
     
    const int N = 20, M = (1 << 16) + 5, mod = 1e6 + 3;
     
    bool MOP1;
     
    int dp[M], Sz[M];
     
    char S[N << 2][N << 2];
     
    inline void Solve(void) {
        int n = Read(), K = Read(), Ans = 0;
        ret(i, 0, n)scanf("%s", S[i] + 1);
        int len = strlen(S[1] + 1);
        clr(dp, 0);
        drep(i, (1 << n) - 1, 0) {
            if (Sz[i] < K)continue;
            int res = 1;
            rep(j, 1, len) {
                int flag = 1, pos = -1;
                ret(k, 0, n)if (i & 1 << k) {
                    if (S[k][j] == '?')continue;
                    if (pos == -1) {
                        pos = S[k][j] - 'a';
                        continue;
                    }
                    if (S[k][j] - 'a' != pos) {
                        flag = 0;
                        break;
                    }
                }
                if (flag && pos == -1)res *= 26, res %= mod;
                if (!flag)res = 0;
            }
            dp[i] += res, Mod(dp[i]);
            if (Sz[i] == K)Ans += dp[i], Mod(Ans);
            for (int j = i & (i - 1); j; j = i & (j - 1)) {
                dp[j] += mod - dp[i], Mod(dp[j]);
            }
        }
        printf("%lld
    ", Ans);
    }
     
    bool MOP2;
     
    void _main(void) {
        int T = Read();
        ret(i, 1, M)Sz[i] = Sz[i & (i - 1)] + 1;
        while (T--)Solve();
    }
     
    signed main() {
        _main();
        return 0;
    }
    
  • 相关阅读:
    centos7安装supervisor
    redis4.0 cluster搭建
    网易cetus数据库中间件安装-读写分离版本
    mongodb副本集基于centos7部署
    C# 单例模式实现
    HttpWebRequest的GET和POST方法
    C#中$的用法
    判断一个表是否存在
    C# 继承的一些解释
    C# 虚方法和抽象方法
  • 原文地址:https://www.cnblogs.com/dsjkafdsaf/p/11630997.html
Copyright © 2011-2022 走看看