在跨年的晚上玩手机被妈妈骂了赶来写题……呜呜呜……但是A题了还是很开心啦,起码没有把去年的题目留到明年去做ヾ(◍°∇°◍)ノ゙也祝大家2019快乐!

  这题显然的 kth min-max 容斥就不说了,不会的还是百度吧……记录一下后面的 dp。感觉挺强强的,%题解……

  首先,min - max 容斥的公式为 : \(max_{K}(S) = \sum_{T\subseteq S}(-1)^{|T|-K}\binom{|T|-1}{K-1}min(T)\)

  但是最后面的 \(min(T)\) 显然不能 \(2 ^ {n}\) 枚举,但又是非线性的求和。所以我们需要一点不一样的dp……考虑到 \(n - K <= 10\),实际上也就是说在上面公式中出现的 \(\binom{|T| - 1}{K - 1}\) 中的 \(K - 1\) 最大不会超过 11。从这个地方入手,设 在前 \(x\) 个元素组成的集合中, \(g_{x, i, j}\) 为所有 \(min(T) = j\) 且 \(|T| = i\) 的子集的方案数,

而\(f_{x, j, k} = \sum_{i = 1}(-1)^{i - k}\binom{i - 1}{k - 1}*g_{x, i, j}\)

考虑向集合中加入第 \(i\) 个元素,不加入的直接继承上一次的。

加入的则需要分析一下(下面的就只讨论包含第 \(i\) 个元素的情况)

考虑从 \(f_{x - 1, j - v, k - 1}\) 转移过来(\(v\) 为 \(p[i]\))

分析:\(f_{x - 1, j - v, k - 1} = \sum_{i = 1}(-1)^{i - k + 1}\binom{i - 1}{k - 2}*g_{x - 1, i, j - v}\)

为了便于观察,我们尽量把 \(f_{x, j, k}\) 也写成一样的形式

\(f_{x, j, k} = \sum_{i = 1}(-1)^{i - k + 1}\binom{i}{k - 1}*g_{x - 1, i, j - v}\)

因为我们有 \(\binom{n}{m} = \binom{n - 1}{m}+\binom{n - 1}{m - 1}\)

所以 \(f_{x, j, k} - f_{x - 1, j- v, k - 1} = \sum_{i = 1}(-1)^{i - k + 1}\binom{i - 1}{k - 1}*g_{x, i, j - v} = -f_{x - 1, j - v, k}\)

所以,完整的式子是:

\(f_{x, j, k} = f_{x - 1, j, k} + f_{x - 1, j - v, k - 1} - f_{x - 1, j - v, k}\)

  这样就可以愉快地递推啦。不过还有一个小小的细节,就是边界的问题。我们只需要每次保存 \(f_{x, 0, 0} = 1\) 即可,因为会从 \(0\) 转移出去的当且仅当 \(v = j\) 即集合中仅有一个元素时。此时显然有 \(f_{x, p[x], 1} = 1\)。

#include <bits/stdc++.h>
using namespace std;
#define maxn 2005
#define maxm 20000
#define mod 998244353
#define int long long
int n, K, m, f[][maxm][];
int ans, now, pre, p[maxn];
int inv[maxm], finv[maxm], fac[maxm]; 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 Up(int &x, int y) { x = (x + y) % mod; if(x < ) x += mod; }
void init()
{
fac[] = , inv[] = inv[] = ; finv[] = ;
for(int i = ; i < maxm; i ++) fac[i] = fac[i - ] * i % mod;
for(int i = ; i < maxm; i ++) inv[i] = (mod - mod / i) * inv[mod % i] % mod;
for(int i = ; i < maxm; i ++) finv[i] = finv[i - ] * inv[i] % mod;
} int C(int n, int m)
{
if(n < m || n < || m < ) return ;
return fac[n] * finv[m] % mod * finv[n - m] % 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 DP()
{
now = , pre = ; f[pre][][] = ;
for(int i = ; i <= n; i ++, swap(now, pre), f[pre][][] = )
for(int j = ; j <= m; j ++)
for(int k = ; k <= K; k ++)
{
f[now][j][k] = f[pre][j][k];
if(j < p[i]) continue;
Up(f[now][j][k], f[pre][j - p[i]][k - ]);
Up(f[now][j][k], -f[pre][j - p[i]][k]);
}
} signed main()
{
n = read(), K = read(), m = read(); init();
for(int i = ; i <= n; i ++) p[i] = read();
K = n - K + ; DP();
for(int i = ; i <= m; i ++)
Up(ans, f[pre][i][K] * m % mod * inv[i] % mod);
printf("%lld\n", ans);
return ;
}

【题解】洛谷P4707重返现世的更多相关文章

  1. 洛谷 P4707 重返现世

    洛谷 P4707 重返现世 k-minimax容斥 有这一个式子:\(E(\max_k(S))=\sum_{T\subseteq S}(-1)^{|T|-k}C_{|T|-1}^{k-1}\min(T ...

  2. 洛谷P4707 重返现世(扩展MinMax容斥+dp)

    传送门 我永远讨厌\(dp.jpg\) 前置姿势 扩展\(Min-Max\)容斥 题解 看纳尔博客去→_→ 咱现在还没搞懂为啥初值要设为\(-1\)-- //minamoto #include< ...

  3. [洛谷P4707] 重返现世

    Description 为了打开返回现世的大门,\(Yopilla\) 需要制作开启大门的钥匙.\(Yopilla\) 所在的迷失大陆有 \(n\) 种原料,只需要集齐任意 \(k\) 种,就可以开始 ...

  4. 洛谷P4707 重返现世 [DP,min-max容斥]

    传送门 前置知识 做这题前,您需要认识这个式子: \[ kthmax(S)=\sum_{\varnothing\neq T\subseteq S}{|T|-1\choose k-1} (-1)^{|T ...

  5. 洛谷 P4707 - 重返现世(扩展 Min-Max 容斥+背包)

    题面传送门 首先看到这种求形如 \(E(\max(T))\) 的期望题,可以套路地想到 Min-Max 容斥 \(\max(S)=\sum\limits_{T\subseteq S}(-1)^{|T| ...

  6. 题解 洛谷P5018【对称二叉树】(noip2018T4)

    \(noip2018\) \(T4\)题解 其实呢,我是觉得这题比\(T3\)水到不知道哪里去了 毕竟我比较菜,不大会\(dp\) 好了开始讲正事 这题其实考察的其实就是选手对D(大)F(法)S(师) ...

  7. 题解 洛谷 P3396 【哈希冲突】(根号分治)

    根号分治 前言 本题是一道讲解根号分治思想的论文题(然鹅我并没有找到论文),正 如论文中所说,根号算法--不仅是分块,根号分治利用的思想和分块像 似却又不同,某一篇洛谷日报中说过,分块算法实质上是一种 ...

  8. 题解-洛谷P5410 【模板】扩展 KMP(Z 函数)

    题面 洛谷P5410 [模板]扩展 KMP(Z 函数) 给定两个字符串 \(a,b\),要求出两个数组:\(b\) 的 \(z\) 函数数组 \(z\).\(b\) 与 \(a\) 的每一个后缀的 L ...

  9. 题解-洛谷P4229 某位歌姬的故事

    题面 洛谷P4229 某位歌姬的故事 \(T\) 组测试数据.有 \(n\) 个音节,每个音节 \(h_i\in[1,A]\),还有 \(m\) 个限制 \((l_i,r_i,g_i)\) 表示 \( ...

随机推荐

  1. linux分区满了,如何进行扩容

    转自:https://blog.csdn.net/valage/article/details/73332147 图片中可以看到挂载点“/”的利用率移到100%,空间不够,所以要对其进行分区. 1.  ...

  2. linux常用命令总结(含选项参数)

    • 用户切换 su              切换到root用户并不切换环境 su - root   切换到root用户并切换环境 su  redhat  切换到redhat不切换环境 • cd切换目 ...

  3. Spring AOP部分源码分析

    Spring源码流程分析-AOP相关 根据Spring源码整理,其中Calculator为自定义的实现方法. AnnotationConfigApplicationContext()加载配置类的流程 ...

  4. golang--性能测试和分析

    前言 测试分为:压力测试.负载测试.性能测试,功能测试等等,其中在开发过程中开发人员经常要写一些test case unit 自己的模块进行功能测试测和性能.在分析出模块的性能瓶颈后开发人员就需要针对 ...

  5. 2019CSUST集训队选拔赛题解(二)

    凛冬将至 Description 维斯特洛大陆的原住民是森林之子,他们长得如孩童一般,善于使用石器,威力值35,用树叶树枝作为衣物,在森林里繁衍生息,与万物和平相处.他们会使用古老的魔法(比如绿之视野 ...

  6. 笨办法学Python - 习题1: A Good First Program

    在windows上安装完Python环境后,开始按照<笨办法学Python>书上介绍的章节进行练习. 习题 1: 第一个程序 第一天主要是介绍了Python中输出函数print的使用方法, ...

  7. 对于新手来说,Python 中有哪些难以理解的概念?

    老手都是从新手一路过来的,提起Python中难以理解的概念,可能很多人对于Python变量赋值的机制有些疑惑,不过对于习惯于求根究底的程序员,只有深入理解了某个事物本质,掌握了它的客观规律,才能得心应 ...

  8. 请教JDBC中的thin和OCI的区别\

    请教JDBC中的thin和OCI的区别 https://zhidao.baidu.com/question/2267123737573204748.html

  9. 记事本APP之Alpha报告

    项目名称 记事本APP 项目版本 Alpha版本 负责人 北京航空航天大学计算机学院 Echo软件团队 联系方式 http://www.cnblogs.com/echo-buaa/ 要求发布日期 20 ...

  10. Daily Scrum1 11.3

    今天是我们团队进入代码实现阶段的第一天,经过一周对上一届项目代码的阅读和研究,队员们已经从代码中分析出我们这次项目将要修改和补充的地方,我们接下来要做的地方就是在两周的时间内将团队项目在alpha阶段 ...