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. Spring boot后台搭建二集成Shiro权限控制

    上一篇文章,实现了用户验证 查看,接下来实现下权限控制 权限控制,是管理资源访问的过程,用于对用户进行的操作授权,证明该用户是否允许进行当前操作,如访问某个链接,某个资源文件等 Apache Shir ...

  2. 【Django单元测试方法】

    一.前言/准备 测Django的东西仅限于在MTV模型.哪些可以测?哪些不可以. 1.html里的东西不能测.①Html里的HTML代码大部分都是写死的②嵌套在html中的Django模板语言也不能测 ...

  3. phpexcel无法导出的解决方法

    phpexcel无法导出的解决方法 <pre> set_time_limit(0); ini_set("memory_limit","512M"); ...

  4. Cookie 允许第三方cookie

    这样本地调线上的接口,就可以使用线上接口生成的cookie了. 或者允许,或者增加白名单.

  5. Hive学习(2)

    什么是hive Hive是基于Hadoop的一个数据仓库工具(E抽取T转换L加载),可以将结构化的数据文件映射为一张表,并提供类SQL查询功能 hive的处理流程 ()将HQL语句转化为一组操作符 ( ...

  6. 通过names.index()方法找到第2个eva值 ,并将其改成EVA

    names= ['alex','rain','peiqi','eva','mac','jack','eva','kangkang','jain']first_index=names.index('ev ...

  7. Golang 实现单例模式

    目录 只适用于单线程环境 支持并发版本 优化并发版本 sync.Once版本 只适用于单线程环境 package main import "fmt" type Single str ...

  8. centos7简单部署rancher

    rancher官网文档地址 https://www.cnrancher.com/docs/rancher/v2.x/cn/overview/ 准备机器 两台虚拟机 192.168.56.100 192 ...

  9. nginx配置比较杂乱的总结

    常用变量 demo uri www.example.com/mock/interface?param1=203&param2=test $args uri中的参数值 ?后面的部分 param1 ...

  10. Linux -- touch 命令

    在Linux中,每个文件都关联一个时间戳,并且每个文件搜会存储最近一次访问的时间.最近一次修改的时间和最近一次变更的时间等信息.所以,无论何时我们创建一个新文件,访问或者修改一个已经存在的文件,文件的 ...