这题好像状压的做法比较的无脑?但想记录一下容斥的做法,感觉自己对于容斥简直一无所知。这道题目容斥的解法我也是看了题解才会的。如有雷同,是我看的(*/ω\*)我们可以首先枚举当前字符串与给定的哪 \(k\) 个匹配(给定的范围很小,枚举一下也只要 \(2^{n}\))。但这样我们求出的是至少与 \(k\) 个字符串匹配的方案数,因为在保证与这 \(k\) 个字符串匹配的时候,我们并没有要求说与其他的 \(n - k\) 个字符串不相匹配。

  我们令上面求出来的数组叫做 \(num[k]\) ,现在要求出恰好与 \(k\) 个串匹配的数组 \(ans[k]\)。一个感觉是 \(num[k] = ans[k] + ans[k + 1] + ... + ans[n]\),但事实上并不是如此。之前我们只考虑 \(k\) 个字符串求出来的 \(num[k]\) 中,有许多重复的方案。例如 \(?a\) 与 \(b?\) 的例子,在枚举到第一个字符串的时候,我们会统计 \(ba\) 一次,而在枚举第二个的时候,我们又会统计到 \(ba\) 一次。那么 \(ans[x]\) 究竟在 \(num[k]\) 中被统计了多少次?应当是 \(C(x, k)\) 次,因为这枚举的 \(k\) 个可能是 \(x\) 个当中的任意 \(k\) 个。

#include <bits/stdc++.h>
using namespace std;
#define maxn 2000
#define int long long
#define mod 1000003
int n, K, len, num[maxn], ans[maxn], C[maxn][maxn];
string s[maxn], S[maxn]; int read()
{
int x = , k = ;
char c; c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} void pre()
{
for(int i = ; i < maxn; i ++) C[i][] = ;
for(int i = ; i < maxn; i ++)
for(int j = ; j < maxn; j ++)
C[i][j] = (C[i - ][j - ] + C[i - ][j]) % mod;
} int Qpow(int x, int timer)
{
int base = ;
for(; timer; timer >>= , x = x * x % mod)
if(timer & ) base = base * x % mod;
return base;
} void dfs(int now, int tot)
{
if(now == n + )
{
int cnt = ;
for(int j = ; j < len; j ++)
{
int t = -;
for(int i = ; i <= tot; i ++)
{
int x = S[i][j] - 'a'; if(x == -) x = -;
if(t != - && (x != - && x != t)) return;
if(t == -) t = x;
}
if(t == -) cnt ++;
}
num[tot] = (num[tot] + Qpow(, cnt)) % mod;
return;
}
dfs(now + , tot);
S[tot + ] = s[now]; dfs(now + , tot + );
} void init()
{
memset(ans, , sizeof(ans));
memset(num, , sizeof(num));
} signed main()
{
int T = read(); pre();
while(T --)
{
n = read(), K = read(); init();
for(int i = ; i <= n; i ++) cin >> s[i];
len = s[].length();
dfs(, );
for(int i = n; i >= K; i --)
{
int t = num[i];
for(int j = i + ; j <= n; j ++)
t = (t - (C[j][i] * ans[j]) % mod + mod) % mod;
ans[i] = t;
}
printf("%lld\n", ans[K]);
}
return ;
}

【题解】SDOI2009Bill的挑战的更多相关文章

  1. poj 3253 Fence Repair 贪心 最小堆 题解《挑战程序设计竞赛》

    地址 http://poj.org/problem?id=3253 题解 本题是<挑战程序设计>一书的例题 根据树中描述 所有切割的代价 可以形成一颗二叉树 而最后的代价总和是与子节点和深 ...

  2. [SDOI2009]Bill的挑战——全网唯一 一篇容斥题解

    全网唯一一篇容斥题解 Description Solution 看到这个题,大部分人想的是状压dp 但是我是个蒟蒻没想到,就用容斥切掉了. 并且复杂度比一般状压低, (其实这个容斥的算法,提出来源于y ...

  3. [BZOJ 1879][SDOI 2009]Bill的挑战 题解(状压DP)

    [BZOJ 1879][SDOI 2009]Bill的挑战 Description Solution 1.考虑状压的方式. 方案1:如果我们把每一个字符串压起来,用一个布尔数组表示与每一个字母的匹配关 ...

  4. noip做题记录+挑战一句话题解?

    因为灵巧实在太弱辽不得不做点noip续下命QQAQQQ 2018 积木大赛/铺设道路 傻逼原题? 然后傻逼的我居然检查了半天是不是有陷阱最后花了差不多一个小时才做掉我做过的原题...真的傻逼了我:( ...

  5. TYVJ-P1864 守卫者的挑战 题解

    P1864 [Poetize I]守卫者的挑战 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 打开了黑魔法师Vani的大门,队员们在迷宫般的路上漫无目的地搜 ...

  6. POJ 2386 Lake Counting 题解《挑战程序设计竞赛》

    地址 http://poj.org/problem?id=2386 <挑战程序设计竞赛>习题 题目描述Description Due to recent rains, water has ...

  7. poj 3069 Saruman's Army 贪心 题解《挑战程序设计竞赛》

    地址 http://poj.org/problem?id=3069 题解 题目可以考虑贪心 尽可能的根据题意选择靠右边的点 注意 开始无标记点 寻找左侧第一个没覆盖的点 再来推算既可能靠右的标记点为一 ...

  8. poj 2431 Expedition 贪心 优先队列 题解《挑战程序设计竞赛》

    地址 http://poj.org/problem?id=2431 题解 朴素想法就是dfs 经过该点的时候决定是否加油 中间加了一点剪枝 如果加油次数已经比已知最少的加油次数要大或者等于了 那么就剪 ...

  9. poj 1182 食物链 并查集 题解《挑战程序设计竞赛》

    地址 http://poj.org/problem?id=1182 题解 可以考虑使用并查集解决 但是并不是简单的记录是否同一组的这般使用 每个动物都有三个并查集 自己 天敌 捕食 并查集 那么在获得 ...

随机推荐

  1. MySQL高级-全局查询日志

    注意:全局查询日志不要在生成环境中启用 一.配置启用 二.编码启用

  2. 数据库路由中间件MyCat - 背景篇(2)

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. MyCat的前世今生 如前文所说,Amoeba.Cobar.MyCat等属于同宗一脉.若Amoeba能继续下 ...

  3. 一个小白的测试环境docker化之路

    本文来自网易云社区 作者:叶子 学习docker搭建测试环境断断续续也有三个多月了,希望记录一下这个过程.常言道,总结过去,展望未来嘛~文章浅显,还望各位大神路过轻拍. 按照国际惯例,先说一下背景: ...

  4. C# 调用webserver 出现:未能从程序集“jgd3jufm, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null”中加载类型

    一般都是 用的动态调用webserver,然后这次用的是固定的 首先 最后 实例化改接口,然后直接传值调用

  5. Java基础知识总结一

    1.何为编程? 编程就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程. 为了使计算机能够理解人的意图,人类就必须要将需解决的问题的思路.方法.和手段通过计算机能够理解 ...

  6. 第八模块:算法&设计模式、企业应用 第1章 常用算法&设计模式学习

    第八模块:算法&设计模式.企业应用 第1章 常用算法&设计模式学习

  7. Java开发工程师(Web方向) - 01.Java Web开发入门 - 第2章.HTTP协议简介

    第2章--HTTP协议简介 HTTP协议简介 Abstract: HTTP协议的特性,HTTP请求/响应的过程,HTTP请求/响应的报文格式等知识,最后会演示如何通过Chrome提供的开发者工具,去跟 ...

  8. JavaScript --经典问题

    JavaScript中如何检测一个变量是一个String类型?请写出函数实现 方法1. function isString(obj){ return typeof(obj) === "str ...

  9. GET请求的写法-jmeter

    第一种写法:可以向post 请求一样写 第二种写法: /pinter/com/getSku?id=${__Random(1,100,rdmNum)}

  10. [SHELL]结构化命令之条件语句

    1.if-then语句  #!/bin/bash username="root" if grep $username /etc/passwd then echo "the ...