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. LIST<>泛型集合取得对象的属性值

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  2. [LeetCode] 248. Strobogrammatic Number III 对称数III

    A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside ...

  3. python+lego ev3的心得总结 随时更新

    一.连接方面 1.试了蓝牙连接,被电脑防火墙拒绝了很多次,很奇怪,明明都pin码都对上了,然后瞬间被踢开. 2.数据线直连,在一台win7上怎么试也不行,在另一台上自动上windows update上 ...

  4. python jieba

    https://www.cnblogs.com/jiayongji/p/7119065.html 安装 pip install jieba 简单用法 结巴分词分为三种模式:精确模式(默认).全模式和搜 ...

  5. java8新特性(2)--接口的默认方法

    1.默认方法的定义和作用 在Java8以前的版本中,由接口定义的方法是抽象的,不包括方法体.JDK8版本的发布改变了这一点,其中给接口添加了一个新的功能:默认方法.默认方法允许为接口方法定义默认实现. ...

  6. 我在LeetCode的首次刷题

    到现在为止,我才发现我的博客一篇感受,心得,体会之言都没有. 今天就来随便扯扯. 刷题,是我最近一直在干的事情.也就每天写一两个.忘了就没写这种.也收藏了好几个刷题网站,当然第一次接触肯定是 WUST ...

  7. 数组中重复的数字(Golang)

    使用哈希表 package main import "fmt" func main() { a := [...]int{2,3,1,0,2,5,3} num := make(map ...

  8. Jmeter参数化(_csvread函数、CSV Data Set Config)

    方法一.Jmeter自带的函数助手——_CSVRead函数 1.数据准备:先在excel存储数据,保存格式选择csv格式.或在记事本存储数据,列之间用英文逗号分隔,保存为txt 2.使用_csvrea ...

  9. delphi indy Idhttp error:1409442E:SSL routines:SSL3_READ_BYTES:tlsv1 alert protocol version

    在使用 indy 中的 idhttp 组件访问 https 网站时,出现如下错误: error:1409442E:SSL routines:SSL3_READ_BYTES:tlsv1 alert pr ...

  10. redis 安装使用 & SpringBoot Redis配置

    1.安装 https://www.cnblogs.com/dingguofeng/p/8709476.html https://www.runoob.com/redis/redis-keys.html ...