题目链接

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))\).

代码

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<cassert>
  5. #include<iostream>
  6. #define llong long long
  7. using namespace std;
  8. inline int read()
  9. {
  10. int x=0; bool f=1; char c=getchar();
  11. for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
  12. for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^'0');
  13. if(f) return x;
  14. return -x;
  15. }
  16. const int N = 1000;
  17. const int S = 1e4;
  18. const int M = 11;
  19. const int P = 998244353;
  20. llong quickpow(llong x,llong y)
  21. {
  22. llong cur = x,ret = 1ll;
  23. for(int i=0; y; i++)
  24. {
  25. if(y&(1ll<<i)) {y-=(1ll<<i); ret = ret*cur%P;}
  26. cur = cur*cur%P;
  27. }
  28. return ret;
  29. }
  30. llong mulinv(llong x) {return quickpow(x,P-2);}
  31. llong a[N+3];
  32. llong dp[S+3][M+2];
  33. int n,m,s;
  34. int main()
  35. {
  36. scanf("%d%d%d",&n,&m,&s); m = n-m+1;
  37. for(int i=1; i<=n; i++) scanf("%lld",&a[i]);
  38. for(int i=1; i<=m; i++) dp[0][i] = P-1;
  39. for(int i=1; i<=n; i++)
  40. {
  41. for(int j=s; j>=a[i]; j--)
  42. {
  43. for(int k=1; k<=m; k++)
  44. {
  45. dp[j][k] = (dp[j][k]+dp[j-a[i]][k-1]-dp[j-a[i]][k]+P)%P;
  46. }
  47. }
  48. }
  49. llong ans = 0ll;
  50. for(int i=1; i<=s; i++)
  51. {
  52. ans = (ans+dp[i][m]*s%P*mulinv(i))%P;
  53. }
  54. printf("%lld\n",ans);
  55. return 0;
  56. }

Luogu P4707 重返现世 (拓展Min-Max容斥、DP)的更多相关文章

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

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

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

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

  3. Luogu P4707 重返现世

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

  4. 【题解】洛谷P4707重返现世

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

  5. 洛谷 P4707 重返现世

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

  6. 【BZOJ3622】已经没有什么好害怕的了 容斥+DP

    [BZOJ3622]已经没有什么好害怕的了 Description Input Output Sample Input 4 2 5 35 15 45 40 20 10 30 Sample Output ...

  7. 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 ...

  8. [CF1086E]Beautiful Matrix(容斥+DP+树状数组)

    给一个n*n的矩阵,保证:(1)每行都是一个排列 (2)每行每个位置和上一行对应位置不同.求这个矩阵在所有合法矩阵中字典序排第几.考虑类似数位DP的做法,枚举第几行开始不卡限制,那么显然之前的行都和题 ...

  9. $bzoj2560$ 串珠子 容斥+$dp$

    正解:容斥+$dp$ 解题报告: 传送门$QwQ$ $umm$虽然题目蛮简练的了但还是有点难理解,,,我再抽象一点儿,就说有$n$个点,点$i$和点$j$之间有$a_{i,j}$条无向边可以连,问有多 ...

随机推荐

  1. C++练习 | 单向链表类模板(包含类模板中静态变量初始化格式)

    #include <iostream> #include <string> using namespace std; template <class T> clas ...

  2. python基础_面向对象

    面向对象定义 把一组数据结构和处理它们的方法组成对象(object),把相同行为的对象归纳为类(class),通过类的封装(encapsulation)隐藏内部细节,通过继承(inheritance) ...

  3. JAVA基础:接口

    接口声明: interface 接口名 实现接口: class 类名 implements 接口名 接口特点: 1. 接口中的成员变量默认都是public.static.final类型的,必须被显式初 ...

  4. The Party and Sweets CodeForces - 1159C (拓排)

    优化连边然后拓排. #include <iostream> #include <sstream> #include <algorithm> #include < ...

  5. WPF ListView多行显示

    //前台 <ListView Margin="14,152,12,74" Name="lvList" SelectionMode="Multip ...

  6. EJS学习(三)之语法规则中

    ⚠️实例均结合node,也就是AMD规范版本 ejs中使用render()表示渲染文本 接收三个参数:模版字符串.data.options,返回一个字符串 const ejs = require('e ...

  7. MySQL数据库基础-JAVA

    数据库 MySQL初步 MySQL基础认知 (Oracle真的是走哪祸害到哪23333) Java多用MySQL和Oracle SQLServer也收费,但是还行,比Oracle便宜,一个差不多3w多 ...

  8. java 关于数字取小数点后两位出现整数0没有的问题

    最近再项目中对取到的一系列带很长小数的数字,展现时要求去小数点后两位显示就可以了 开始我是以下写法: double  a =  0.1234455; DecimalFormat decimalForm ...

  9. javascript原型与原型链个人理解

    想了解原型和原型链,我觉得首先我们得知道javascript里有一个Object 与 Function,它俩都是构造函数,当然函数也是一个对象.我们打印Object 与 Function看一下, co ...

  10. 关于IDEA顶部栏隐藏问题,

    那天手残,点到了 IDEA顶部菜单栏 > View > Appearance >Main Menu ,然后取消了勾选 然后就成了这个样子,没了顶部栏,恢复不过来,不知道如何进行设置 ...