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] 274. H-Index H指数

    Given an array of citations (each citation is a non-negative integer) of a researcher, write a funct ...

  2. 【剑指offer】面试题 19. 正则表达式匹配

    面试题 19. 正则表达式匹配

  3. [转帖]Linux教程(21)-Linux条件循环语句

    Linux教程(21)-Linux条件循环语句 2018-08-24 16:49:03 钱婷婷 阅读数 60更多 分类专栏: Linux教程与操作 Linux教程与使用   版权声明:本文为博主原创文 ...

  4. Kafka Streams | 流,实时处理和功能

    1.目标 在我们之前的Kafka教程中,我们讨论了Kafka中的ZooKeeper.今天,在这个Kafka Streams教程中,我们将学习Kafka中Streams的实际含义.此外,我们将看到Kaf ...

  5. tft_LCD一些引脚极性设置方法:vsync, hsync, VBLANK

    转载:https://blog.csdn.net/u014170207/article/details/52662988/ 在RGB模式中,LCD数据的扫描是以行为单位的.HSYNC是水平同步信号.P ...

  6. ArcGIS 字段计算器 Python 坑

    最近要处理个简单数据,一个字段中为文本类型,包含各种描述.要求是包含平方米的数值提取出来,变成数值,如果包含多个,则把各个值累加起来. 比如 字段值为 “非法占用100平方米” 处理后结果为 100 ...

  7. quartz2.3.0(七)调度器中断任务执行,手动处理任务中断事件

    job任务类 package org.quartz.examples.example7; import java.util.Date; import org.slf4j.Logger; import ...

  8. 创建包含CRUD操作的Web API接口-第一部

    在这里,我们将创建一个新的Web API项目,它将使用实体框架实现Get,POST.PUT和DELETE方法来实现CRUD操作. 首先,在Visual Studio 2013 for Web expr ...

  9. VS 引用dll版本冲突问题

    1.删除项目中的对应引用: 2.如果是有用到NetGet引用的删除项目中的packages里面的对应包文件: 3.如果是在NetGet中引用的注释项目中packages.config对应的插件名: 4 ...

  10. mysql数据库备份之主从同步配置

    主从同步意义? 主从同步使得数据可以从一个数据库服务器复制到其他服务器上,在复制数据时,一个服务器充当主服务器(master),其余的服务器充当从服务器(slave).因为复制是异步进行的,所以从服务 ...