Luogu P4707 重返现世 (拓展Min-Max容斥、DP)
题目链接
https://www.luogu.org/problem/P4707
题解
最近被神仙题八连爆了……
首先Min-Max容斥肯定都能想到,问题是这题要用一个扩展版的——Kth Min-Max容斥
这个东西需要对Min-Max容斥的本质有着比较深刻的理解。
首先我们从另一个角度证明Min-Max容斥的正确性: \(\max(S)=\sum_{T\in S}f(|T|)\min(T)\), 对于第\((x+1)\)大来说它被计算的次数是\(\sum_{k\ge 0} {x\choose k}f(k+1)\),则有\([x=0]=\sum_{k\ge 0} {x\choose k}f(k+1)\), 二项式反演之后令\(f(k)=(-1)^{k-1}\)即可达到目的。
那么考虑把刚才式子中\([x=0]\)换成\([x=k-1]\)会怎样? 依然采取构造系数的思路,得出的结果是: \(f[x]=(-1)^{x-k}{x-1\choose k-1}\).
问题相当于求第\(K\)大的期望,所以可以转化成子集最小值: \(\text{kthmax}(S)=\sum_{T\in S}(-1)^{|T|-K}{|T|-1\choose k-1}\min(T)=\sum_{T\in S}\frac{m}{p_T}(-1)^{|T|-K}{|T|-1\choose k-1}\), 其中\(p_T=\sum_{i\in T} p_i\)
这个东西可以用一个dp来搞: 设\(dp[i][j][k]\)表示前\(i\)个数\(p\)之和为\(j\), 当组合数的下指标为\(k\)时每种方案乘以容斥系数之和。
考虑转移: 如果第\(i\)个元素不属于\(T\), 显然是加上\(dp[i-1][j][k]\); 如果属于\(T\), 那么要求的组合数\({|T|-1\choose k-1}={|T|-2\choose k-1}+{|T|-2\choose k-2}\), 对于前一项直接是\(dp[i-1][j-p_i][k]\), 对于后一项因为是从\(k-1\)转移过来,所以要多乘个\(-1\), 最终结果是减去\((dp[i-1][j-p_i][k]-dp[i-1][j-p_i][k-1])\).
然而这个dp的边界问题很难处理。这时我们不妨脱离实际问题,去思考一下组合数在指标为负数时的定义,直接代入可得\(dp[0][0][k]=-1 (k>0)\).
(然而感觉这种边界设置方法并不严谨)
时间复杂度\(O(nm(n-k))\).
代码
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<iostream>
#define llong long long
using namespace std;
inline int read()
{
int x=0; bool f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^'0');
if(f) return x;
return -x;
}
const int N = 1000;
const int S = 1e4;
const int M = 11;
const int P = 998244353;
llong quickpow(llong x,llong y)
{
llong cur = x,ret = 1ll;
for(int i=0; y; i++)
{
if(y&(1ll<<i)) {y-=(1ll<<i); ret = ret*cur%P;}
cur = cur*cur%P;
}
return ret;
}
llong mulinv(llong x) {return quickpow(x,P-2);}
llong a[N+3];
llong dp[S+3][M+2];
int n,m,s;
int main()
{
scanf("%d%d%d",&n,&m,&s); m = n-m+1;
for(int i=1; i<=n; i++) scanf("%lld",&a[i]);
for(int i=1; i<=m; i++) dp[0][i] = P-1;
for(int i=1; i<=n; i++)
{
for(int j=s; j>=a[i]; j--)
{
for(int k=1; k<=m; k++)
{
dp[j][k] = (dp[j][k]+dp[j-a[i]][k-1]-dp[j-a[i]][k]+P)%P;
}
}
}
llong ans = 0ll;
for(int i=1; i<=s; i++)
{
ans = (ans+dp[i][m]*s%P*mulinv(i))%P;
}
printf("%lld\n",ans);
return 0;
}
Luogu P4707 重返现世 (拓展Min-Max容斥、DP)的更多相关文章
- 洛谷P4707 重返现世(扩展MinMax容斥+dp)
传送门 我永远讨厌\(dp.jpg\) 前置姿势 扩展\(Min-Max\)容斥 题解 看纳尔博客去→_→ 咱现在还没搞懂为啥初值要设为\(-1\)-- //minamoto #include< ...
- 洛谷 P4707 - 重返现世(扩展 Min-Max 容斥+背包)
题面传送门 首先看到这种求形如 \(E(\max(T))\) 的期望题,可以套路地想到 Min-Max 容斥 \(\max(S)=\sum\limits_{T\subseteq S}(-1)^{|T| ...
- Luogu P4707 重返现世
题目描述 为了打开返回现世的大门,Yopilla 需要制作开启大门的钥匙.Yopilla 所在的迷失大陆有 \(n\) 种原料,只需要集齐任意 \(k\) 种,就可以开始制作. Yopilla 来到了 ...
- 【题解】洛谷P4707重返现世
在跨年的晚上玩手机被妈妈骂了赶来写题……呜呜呜……但是A题了还是很开心啦,起码没有把去年的题目留到明年去做ヾ(◍°∇°◍)ノ゙也祝大家2019快乐! 这题显然的 kth min-max 容斥就不说了, ...
- 洛谷 P4707 重返现世
洛谷 P4707 重返现世 k-minimax容斥 有这一个式子:\(E(\max_k(S))=\sum_{T\subseteq S}(-1)^{|T|-k}C_{|T|-1}^{k-1}\min(T ...
- 【BZOJ3622】已经没有什么好害怕的了 容斥+DP
[BZOJ3622]已经没有什么好害怕的了 Description Input Output Sample Input 4 2 5 35 15 45 40 20 10 30 Sample Output ...
- HDU 5794 A Simple Chess (容斥+DP+Lucas)
A Simple Chess 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5794 Description There is a n×m board ...
- [CF1086E]Beautiful Matrix(容斥+DP+树状数组)
给一个n*n的矩阵,保证:(1)每行都是一个排列 (2)每行每个位置和上一行对应位置不同.求这个矩阵在所有合法矩阵中字典序排第几.考虑类似数位DP的做法,枚举第几行开始不卡限制,那么显然之前的行都和题 ...
- $bzoj2560$ 串珠子 容斥+$dp$
正解:容斥+$dp$ 解题报告: 传送门$QwQ$ $umm$虽然题目蛮简练的了但还是有点难理解,,,我再抽象一点儿,就说有$n$个点,点$i$和点$j$之间有$a_{i,j}$条无向边可以连,问有多 ...
随机推荐
- 从入门到自闭之Python高阶函数
高阶函数:内部帮忙做了一个for循环 filter:筛选过滤 语法: filter(function,iterable) function: 1.指定过滤规则(函数的内存地址) 2.用来筛选的函数,在 ...
- Spring防止Xss配置
web.xml配置 <!-- xss过滤器 --> <filter> <filter-name>XssFilter</filter-name> < ...
- Codeforces 1221D. Make The Fence Great Again
传送门 容易想到 $dp$,但是如果直接设 $f[i][j]$ 表示修正完前 $i$ 个位置,第 $i$ 个位置增加了 $j$ 高度显然是不行的 考虑有性质,发现每个位置只会被左右两个位置影响而改变, ...
- response.getWriter().wirte和out.print()的区别
1.首先介绍write()和print()方法的区别: (1).write():仅支持输出字符类型数据,字符.字符数组.字符串等 (2).print():可以将各种类型(包括Object)的数据通 ...
- golang(2):基本数据类型和操作符
1). 文件名 & 关键字 & 标识符 . 所有go源码都以 .go 结尾 . 标识符以字母或下划线开头,大小写敏感 . _ 是特殊标识符,用来忽略结果 . 保留关键字 golang ...
- Git复习(二)之远程仓库、注册GitHub账号、SSH警告、使用GitHub
远程仓库 Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上.怎么分布呢?最早,肯定只有一台机器有一个原始版本库,此后,别的机器可以“克隆”这个原始版本库,而且每台机器的版本库其实都 ...
- 笔记本电脑重装win7/win10系统教程
由于笔记本第一次重装系统会出现系统装不上,还有出现找不到有效硬盘分区,等等问题,然后这篇文章主要讲解BIOS设置的方法,用此BIOS设置,电脑用原本安装系统的方式,能有效地解决以上问题,这有两种方法解 ...
- 【Lucene】小谈lucene的BooleanQuery查询对象
BooleanQuery用于逻辑查询,即所谓的组合查询,具体的逻辑关系如下: 一个具体的使用测试,如下:
- 构建docker基本镜像
1.准备: 创建一个目录oldboy-hello 2.编写Dockerfile 内容如下,只有三行 FROM scratch ADD hello / CMD ["/hello"] ...
- 2.flask模板--jinja2
1.jinja2模板介绍和查找路径 import os from flask import Flask, render_template # 之前提到过在渲染模板的时候,默认会从项目根目录下的temp ...