Codeforces Round #581 (Div. 2)-E. Natasha, Sasha and the Prefix Sums-动态规划+组合数学


【Problem Description】

​ 给你\(n\)个\(1\),\(m\)个\(-1\),他们任意排列有\(\frac{(n+m)!}{n!\cdot m!}\)中排列,每种排列都有一个最大前缀和(可能为\(0\)),求所有排列的最大前缀和之和为多少。

【Solution】

​ 定义\(dp[i][j]\)表示有\(i\)个\(1\),\(j\)个\(-1\)时所有排列的最大前缀和之和为\(dp[i][j]\)。则状态转移方程为:\(dp[i][j]=dp[i-1][j]+C_{i+j-1}^{j}+dp[i][j-1]-C_{i+j-1}^{i}+k[i][j]\)。其中\(k[i][j]\)表示有\(i\)个\(1\),\(j\)个\(-1\)时最大前缀和为\(0\)的排列的个数。

​ 其中\(dp[i-1][j]+C_{i+j-1}^j\)表示新增加一个数字\(1\)时,将其放到所有排列的最前端,则所有排列的最大前缀和都增加\(1\),且总共有\(C_{i+j-1}^j\)种排列,所以在原来基础上增加了\(C_{i+j-1}^j\)。

​ \(dp[i][j-1]-C_{i+j-1}^i+k[i][j]\)表示新增加一个数字\(-1\)时,同上所有排列的最大前缀和减少\(1\),除了最大前缀和为\(0\)的排列。

​ 那为什么\(i-1\)个\(1\),\(j\)个\(-1\)的所有排列个数为\(C_{i+j-1}^j\)呢?是因为根据多重集合的排列公式\(\frac{((i-1)+j)!}{(i-1)!\cdot j!}\)得到的。

​ 最大前缀和\(k[i][j]\)怎么求呢?\(k[i][j]=k[i-1][j]+k[i][j-1]\)。表示在保证\(i\le j\)的情况下,新增加一个数字\(1\),将其放到末端的排列数加上新增加一个\(-1\),将其放在末端的排列数。

​ 最后一个问题,为什么\(dp\)数组中\(1,-1\)要放在前端,\(k\)数组中\(1,-1\)要放在末端,并且为什么不能同时放在前端和后端以及任意其他位置?\(dp\)数组中放在前端是因为要求最大前缀和最大,比如将多出的\(1\)放在后端一定不可能使得最大前缀和最大,\(k\)数组中放在后端是因为要求最大前缀和为\(0\),比如将多出的\(1\)放在前端,那么最大前缀和最小就等于\(1\)。

​ 不能同时放在其他位置是因为只要放一个位置就包含了所有可能的排列,若同时放在其他位置就重复计算了可能出现的排列数。例如有\(i\)个\(1\),\(j\)个\(-1\),可知它们的所有排列个数为\(C_{i+j}^j\),若有\(i-1\)个\(1\),\(j\)个\(-1\),则共有的排列个数为\(C_{i+j-1}^j\),若有\(i\)个\(1\),\(j\)个\(-1\),则共有的排列个数为\(C_{i+j-1}^i=C_{i+j-1}^{j-1}\)。它们之间的关系就是:

\[C_{i+j}^{j}=C_{i+j-1}^{j}+C_{i+j-1}^{j-1}
\]

由帕斯卡公式可知上式一定成立。所以可以知道由数组的含义决定了放在哪个位置,由上述关系决定了只能放\(1\)个位置。


【Code】

/*
* @Author: Simon
* @Date: 2019-08-28 19:32:35
* @Last Modified by: Simon
* @Last Modified time: 2019-08-28 20:26:23
*/
#include<bits/stdc++.h>
using namespace std;
typedef int Int;
#define int long long
#define INF 0x3f3f3f3f
#define maxn 2005
const int mod=998244853;
int dp[maxn][maxn]/*i个1,j个-1的所有排列的最大前缀和之和为dp[i][j]*/,k[maxn][maxn]/*i个1,j个-1的所有排列的最大前缀和为0的个数*/;
int bit[maxn<<1],C[maxn<<1][maxn<<1]/*组合数组*/;
Int main(){
#ifndef ONLINE_JUDGE
//freopen("input.in","r",stdin);
//freopen("output.out","w",stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
int n,m;cin>>n>>m;
bit[0]=1;C[0][0]=1;
for(int i=1;i<=n+m;i++) bit[i]=bit[i-1]*i%mod,C[i][0]=1;
for(int i=1;i<=m;i++) k[0][i]=1;
for(int i=1;i<=n+m;i++){ //预处理
for(int j=1;j<=n+m;j++){
if(j>=i&&i<=n&&j<=m) k[i][j]=(k[i-1][j]+k[i][j-1])%mod;
if(i>=j) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
}
}
for(int i=1;i<=n;i++) dp[i][0]=i;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
dp[i][j]=((dp[i-1][j]+C[i+j-1][j]+dp[i][j-1]-C[i+j-1][i]+k[i][j-1])%mod+mod)%mod;
}
}
cout<<(dp[n][m]+mod)%mod<<endl;
#ifndef ONLINE_JUDGE
cout<<endl;system("pause");
#endif
return 0;
}

Codeforces Round #581 (Div. 2)-E. Natasha, Sasha and the Prefix Sums-动态规划+组合数学的更多相关文章

  1. CodeForces 1204E"Natasha, Sasha and the Prefix Sums"(动态规划 or 组合数学--卡特兰数的应用)

    传送门 •参考资料 [1]:CF1204E Natasha, Sasha and the Prefix Sums(动态规划+组合数) •题意 由 n 个 1 和 m 个 -1 组成的 $C_{n+m} ...

  2. Codeforces Round #425 (Div. 2) Problem A Sasha and Sticks (Codeforces 832A)

    It's one more school day now. Sasha doesn't like classes and is always bored at them. So, each day h ...

  3. 【Codeforces Round #425 (Div. 2) A】Sasha and Sticks

    [Link]: [Description] [Solution] 傻逼题; 获取n/k; 对n/k的奇偶性讨论一下就好 [NumberOf WA] 0 [Reviw] [Code] #include ...

  4. Codeforces Round #581 (Div. 2)

    A:暴力. #include<cstdio> #include<cstring> #include<iostream> #include<algorithm& ...

  5. 01串LIS(固定串思维)--Kirk and a Binary String (hard version)---Codeforces Round #581 (Div. 2)

    题意:https://codeforc.es/problemset/problem/1204/D2 给你一个01串,如:0111001100111011101000,让你改这个串(使0尽可能多,任意 ...

  6. Codeforces Round #581 (Div. 2) C. Anna, Svyatoslav and Maps (Floyd 算法,最短路)

    C. Anna, Svyatoslav and Maps time limit per test2 seconds memory limit per test256 megabytes inputst ...

  7. D2. Kirk and a Binary String (hard version) D1 Kirk and a Binary String (easy version) Codeforces Round #581 (Div. 2) (实现,构造)

    D2. Kirk and a Binary String (hard version) time limit per test1 second memory limit per test256 meg ...

  8. Codeforces Round #581 (Div. 2) B. Mislove Has Lost an Array (贪心)

    B. Mislove Has Lost an Array time limit per test1 second memory limit per test256 megabytes inputsta ...

  9. Codeforces Round #581 (Div. 2)A BowWow and the Timetable (思维)

    A. BowWow and the Timetable time limit per test1 second memory limit per test256 megabytes inputstan ...

随机推荐

  1. [LeetCode] 40. Combination Sum II 组合之和 II

    Given a collection of candidate numbers (candidates) and a target number (target), find all unique c ...

  2. Java高级面试题整理(附答案)

    这是我收集的10道高级Java面试问题列表.这些问题主要来自 Java 核心部分 ,不涉及 Java EE 相关问题.你可能知道这些棘手的 Java 问题的答案,或者觉得这些不足以挑战你的 Java ...

  3. IIS中发布FTP支持断点续传

    IIS10中发布FTP默认就是支持断点续传的.

  4. SQL中EXPLAIN命令详解---(转)

    MySQL Explain详解   在日常工作中,我们会有时会开慢查询去记录一些执行时间比较久的SQL语句,找出这些SQL语句并不意味着完事了,些时我们常常用到explain这个命令来查看一个这些SQ ...

  5. 【LeetCode】最接近的三数之和【排序,固定k1,二分寻找k2和k3】

    给定一个包括 n 个整数的数组 nums 和 一个目标值 target.找出 nums 中的三个整数,使得它们的和与 target 最接近.返回这三个数的和.假定每组输入只存在唯一答案. 例如,给定数 ...

  6. 关于close_wait状态的理解

    以web服务器产生大量的close_wait状态为例 1.close_wait状态介绍: 客户端主动关闭连接,服务器接收到客户端的FIN,但是还没有发送自己的FIN,此时的状态为close_wait状 ...

  7. nginx实现tcp负载均衡

    1 安装支持库 yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel yum install pcre-d ...

  8. 【转帖】vim/sed/awk/grep等文件批处理总结

    vim/sed/awk/grep等文件批处理总结 https://www.cnblogs.com/cangqiongbingchen/p/9760544.html Vim相关操作 1.基础 * 和 # ...

  9. Java生成菜单树(目录树)的几种方式

    本文介绍两种不同生成多级目录树的方式:1. 递归生成,2.  map+list 集合生成.最下方会附上完整代码. 生成树的基本规则:子节点的par_id等于父节点的id. 1. 实体类 import ...

  10. 20191210-RobotFramework常见问题解决

    附加-问题解决 1.   执行robot用例的时候提示WebDriverException: Message: invalid argument: can't kill an exited proce ...