前言

本文中的排列指由n个1, m个-1构成的序列中的一种。

题目这么长不吐槽了,但是这确实是一道好题。

题解

DP题话不多说,直接状态/变量/转移。

状态

我们定义f表示"最大prefix sum"之和

变量

f[i][j]为有i个1,j个-1的"最大prefix sum"之和

转移

我们记C[i][j]为\(\left(\begin{matrix} i \\ j\end{matrix}\right)\),那么:

\[f[i][j] = \left\{\begin{matrix} f[i-1][j]+1 \times C[i+j-1][i-1] \\ f[i][j-1]+(-1)\times(C[i+j-1][j-1]-k[i][j-1])\end{matrix}\right.
\]

k[i][j]表示有i个1,j个-1的最大前缀和刚好为0的排列的个数

那么上式是如何推出的呢?

我们固定地认为每当新加入一个数的时候将该数插入序列的最前方,这种设定仍然保证了动规涵盖所有珂能的排列。

如果我们插入的是一个1,不管先前的序列排列如何,最大prefix sum一定会加1,由于i-1个1,j个-1对应的序列有\(\left(\begin{matrix} i+j-1 \\ i\end{matrix}\right)\)种排列方法,所以当前状态增加的贡献为\(\left(\begin{matrix} i+j-1 \\ i\end{matrix}\right)\)。

如果我们插入的是一个-1,情况于上面是完全相同的,但是注意到,如果有一种排列它本身的"最大prefix sum"为0,那么我们不应当把它计入贡献(因为"最大prefix sum"最小为0),所以要减去k[i][j]。

组合数显然珂以通过杨辉三角递推解决。

那么现在我们的问题就在于k[i][j]如何处理。

我们先给出k[i][j]的递推式。

\[k[i][j]=\left\{\begin{matrix}i=0 & k[i][j]=1 \\ j=0 & k[i][j]=0 \\ i > j & k[i][j]=0 \\ \text{其余情况} & k[i][j]=k[i-1][j]+k[i][j-1]\end{matrix}\right.
\]

这个递推式珂能有点晦涩,但是一种简单的理解方式是找出由当前状态向外转移的方程式,然后再转化为以上方程式。

于是我们解决了此题。

代码

没有卡常,见谅。

#include <cstdio>
#define MOD 998244853 long long f[2005][2005];
long long k[2005][2005];
long long C[4005][4005]; int main(){
int n, m; scanf("%d %d", &n, &m);
for (register int i = 0; i <= n; ++i)
for (register int j = 0; j <= m; ++j){
if (i == 0) k[i][j] = 1;
else if (j == 0) k[i][j] = 0;
else if (i > j) k[i][j] = 0;
else k[i][j] = (k[i - 1][j] + k[i][j - 1]) % MOD;
}
C[0][0] = C[1][0] = C[1][1] = 1;
for (register int i = 2; i <= n + m; ++i){
C[i][0] = 1;
for (register int j = 1; j <= i; ++j)
C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % MOD;
}
for (register int i = 0; i <= n; ++i)
f[i][0] = i, f[0][i] = 0;
for (register int i = 1; i <= n; ++i)
for (register int j = 1; j <= m; ++j)
f[i][j] = ((f[i - 1][j] + C[i + j - 1][i - 1]) % MOD + (f[i][j - 1] - C[i + j - 1][j - 1] + k[i][j - 1] + MOD) % MOD) % MOD;
printf("%I64d", f[n][m]);
return 0;
}

[CF1204E]Natasha,Sasha and the Prefix Sums 题解的更多相关文章

  1. CF1204E Natasha, Sasha and the Prefix Sums (卡塔兰数推理)

    题面 题解 把题意变换一下,从(0,0)走到(n,m),每次只能网右或往上走,所以假设最大前缀和为f(n),那么走的时候就要到达但不超过 y = x-f(n) 这条线, 我们可以枚举答案,然后乘上方案 ...

  2. CF1204E Natasha, Sasha and the Prefix Sums(组合数学)

    做法一 \(O(nm)\) 考虑\(f(i,j)\)为i个+1,j个-1的贡献 \(f(i-1,j)\)考虑往序列首添加一个\(1\),则贡献\(1\times\)为序列的个数:\(C(j+i-1,i ...

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

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

  4. CodeForces - 1204E Natasha, Sasha and the Prefix Sums (组合数学,卡特兰数扩展)

    题意:求n个1,m个-1组成的所有序列中,最大前缀之和. 首先引出这样一个问题:使用n个左括号和m个右括号,组成的合法的括号匹配(每个右括号都有对应的左括号和它匹配)的数目是多少? 1.当n=m时,显 ...

  5. E. Natasha, Sasha and the Prefix Sums

    http://codeforces.com/contest/1204/problem/E 给定n个 1 m个 -1的全排 求所有排列的$f(a) = max(0,max_{1≤i≤l} \sum_{j ...

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

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

  7. 【题解】【数组】【Prefix Sums】【Codility】Genomic Range Query

    A non-empty zero-indexed string S is given. String S consists of N characters from the set of upper- ...

  8. 【题解】【数组】【Prefix Sums】【Codility】Passing Cars

    A non-empty zero-indexed array A consisting of N integers is given. The consecutive elements of arra ...

  9. Codeforces 837F Prefix Sums

    Prefix Sums 在 n >= 4时候直接暴力. n <= 4的时候二分加矩阵快速幂去check #include<bits/stdc++.h> #define LL l ...

随机推荐

  1. mysql拆分逗号一列变多行

    需求: SELECT ), ) FROM TABLE a INNER JOIN mysql.help_topic b )

  2. [转帖]Windows 下如何配置Oracle ASM???

    Windows 下如何配置Oracle ASM??? candon123关注10人评论16725人阅读2011-02-09 21:40:57   本篇介绍了如何在windows下创建裸设备,并创建AS ...

  3. Python中的 _init__和 _new__的区别

    使用python 的面向对象写过程序之后,相信童鞋对 __init__ 方法已经非常的熟悉了.这个方法通常是 在初始化一个实例的时候使用的. 例如: class MysqlConnector(obje ...

  4. 通过Playbook部署LAMP

    Ansible的PlayBook文件格式为YAML语言,所以希望你在编写PlayBook前对YAML语法有一定的了解,否则在运行PlayBook的时候经常碰到语法错误提示,这里我们通过介绍批量部署LA ...

  5. java多线程之并发编程

    1.并发不一定比串行更快 因为并发有线程创建和上下文切换的开销 2.java的并发采用内存共享模型 3.单线程中重排序不会影响到结果 但多线程中重排序可能会影响到结果 4.votaile变量 当线程A ...

  6. SQL----Scalar 函数

    UCASE() 函数 UCASE 函数把字段的值转换为大写. SQL UCASE() 语法 SELECT UCASE(column_name) FROM table_name SQL UCASE() ...

  7. 关于swiper 4的coverflowEffect(3d)

    轮播效果: HTML: <div class="swiper-container successful_swiper"> <div class="swi ...

  8. java 语言多线程可见性(synchronized 和 volatile 学习)

    共享变量可见性实现的原理 java 语言层面支持的可见性实现方式: synchronized volatile 1. synchronized 的两条规定: 1 线程解锁前,必须把共享变量的最新值刷新 ...

  9. 转 eclipse 快捷键

    1. ctrl+shift+r:打开资源 这可能是所有快捷键组合中最省时间的了.这组快捷键可以让你打开你的工作区中任何一个文件,而你只需要按下文件名或mask名中的前几个字母,比如applic*.xm ...

  10. 使用CLI 3 创建发布Web Components

    本文翻译自:codementor 翻译不当之处,欢迎指正交流 Web Components是web平台的未来吗?关于这一问题支持和反对的观点有很多.事实上浏览器对Web Components的支持正在 ...