这题好像状压的做法比较的无脑?但想记录一下容斥的做法,感觉自己对于容斥简直一无所知。这道题目容斥的解法我也是看了题解才会的。如有雷同,是我看的(*/ω\*)我们可以首先枚举当前字符串与给定的哪 \(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. Drupal 判断匿名用户必须先登录的解决方法

    要实现如果是匿名用户点击checkout链接,要求先登录 方案一.通过添加Rules规则实现 EVENT:After adding a product to the cart Conditions : ...

  2. Dota2一直 正在登录服务器的解决办法

    然后:1: c:\Windows\System32\drivers\etc\ 2:双击hosts文件,用记事本方式打开3:复制以下并粘贴至以记事本方式打开的hosts最后面111.221.33.253 ...

  3. leetcode笔记10 Intersection of Two Arrays(求交集)

    问题描述: Given two arrays, write a function to compute their intersection. Example:Given nums1 = [1, 2, ...

  4. 「日常训练」Watering Flowers(Codeforces Round #340 Div.2 C)

    题意与分析 (CodeForces 617C) 题意是这样的:一个花圃中有若干花和两个喷泉,你可以调节水的压力使得两个喷泉各自分别以\(r_1\)和\(r_2\)为最远距离向外喷水.你需要调整\(r_ ...

  5. tpo-10 C1 How to get photographs exhibited

    第 1 段 1.Listen to a conversation between a student and her Photography professor. 听一段学生和摄影学教授的对话. 第 ...

  6. Unity 特殊目录

    其他目录 Application.persistentDataPath:webGL平台只能使用这个

  7. Python-3.6 安装pycrypto 2.6

    最近接触公司后台管理系统的开发,其中涉及到加密模块pycrypto. 重点来了!!!!敲黑板!!!! pycrypto在PyCharm中跟其他的模块不一样,pip install pycrypto安装 ...

  8. adb 在windows7中的使用

    我的系统环境是win7 x64 首先放上资源链接:https://pan.baidu.com/s/1eTV5qX8 密码:2ejw 第一步: 配置环境变量,将adb.exe的路径添加到PATH里面去: ...

  9. Java进阶知识点:服务端高并发的基石 - NIO与Reactor AIO与Proactor

    一.背景 要提升服务器的并发处理能力,通常有两大方向的思路. 1.系统架构层面.比如负载均衡.多级缓存.单元化部署等等. 2.单节点优化层面.比如修复代码级别的性能Bug.JVM参数调优.IO优化等等 ...

  10. 开源自动驾驶仿真平台 AirSim (1) - Unreal Engine

    AirSim 官方Github: https://github.com/Microsoft/AirSim AirSim 是微软的开源自动驾驶仿真平台(其实它还能做很多事情,这里主要用于自动驾驶仿真研究 ...