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

    一.dubbo的main启动在使用上面会简单的多,但是需要做一些简单的配置. dubbo.spring.config=classpath*:META-INF/spring/*.xml 备注:这个是默认 ...

  2. L010 linux命令及基础手把手实战总结

    一转眼都快两周没更新了,最近实在太忙了,这两周的时间断断续续的把L010学完了,短短的15节课,确是把前10节的课程全部的运用一遍,从笔记到整理,再到重新理解,最后发布到微博,也确实提升了一些综合性能 ...

  3. Bing wallpaper api

    list: http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-cn idx:-1为明天,1为 ...

  4. package.json中的devDependencies和dependencies有啥区别?

    如果你的项目是发布到npm的一个包, 那么这个包的package.json中的dependencies中的依赖是会被下载下来到这个包的node_modules文件夹中的(如果你的项目本身没有这个依赖) ...

  5. hdu2037今年暑假不AC(贪心,活动安排问题)

    今年暑假不AC Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submi ...

  6. 域名、IP地址、URL关系

    域名是个文字形式记录的IP地址 IP地址是计算机在网络中的门牌号! URL是网页地址 例如1: http://zhidao.baidu.com/question/14674128.html 是URL ...

  7. 索引值迭代-enumerate

    你想在迭代一个序列的同时跟踪正在被处理的元素索引?内置的enumerate() 函数可以很好的解决这个问题: list_c = ['a', 'b', 'c'] for i, c in enumerat ...

  8. HDU 2490 Parade(DPの单调队列)(2008 Asia Regional Beijing)

    Description Panagola, The Lord of city F likes to parade very much. He always inspects his city in h ...

  9. lintcode-187-加油站

    187-加油站 在一条环路上有 N 个加油站,其中第 i 个加油站有汽油gas[i],并且从第_i_个加油站前往第_i_+1个加油站需要消耗汽油cost[i]. 你有一辆油箱容量无限大的汽车,现在要从 ...

  10. lintcode-171-乱序字符串

    171-乱序字符串 给出一个字符串数组S,找到其中所有的乱序字符串(Anagram).如果一个字符串是乱序字符串,那么他存在一个字母集合相同,但顺序不同的字符串也在S中. 注意事项 所有的字符串都只包 ...