CodeForces 1204E"Natasha, Sasha and the Prefix Sums"(动态规划 or 组合数学--卡特兰数的应用)
•参考资料
•题意
由 n个1和m个-1组成的 $C_{n+m}^{n}$ 个序列;对所有序列的最大前缀和求和;
并规定最大前缀和最小是
0;
•题解
定义 $(i,j)$ 表示序列由 i 个 1,j 个 -1 组成;
$(i,j)$ 共有 $C_{i+j}^{i}$ 种不同的组合方式;
$(i-1,j)$ 共有 $C_{i+j-1}^{i-1}$ 种不同的组合方式;
$(i,j-1)$ 共有 $C_{i+j-1}^{i}$ 种不同的组合方式;
如果同时在 $(i-1,j)$ 的 $C_{i+j-1}^{i-1}$ 和 $(i,j-1)$ 的 $C_{i+j-1}^{i}$ 种组合方式的末尾或开头分别插入 1 或 -1;
那便是 $(i,j)$ 的不同的组合方式的种类数,即 $C_{i+j}^{i}=C_{i+j-1}^{i-1}+C_{i+j-1}^{i}$;
根据 n,m 的范围($\leq 2000$),考虑用 DP 解决这道题目;
首先,定义 $dp[i][j]$ 表示由 $(i,j)$ 组成的 $C_{i+j}^{i}$ 个序列,对所有序列的最大前缀和求和后的结果;
有上述前置知识,很容易想到 $(i,j)$ 可由 $(i-1,j)$ 和 $(i,j-1)$ 得到;
这也就是说,$dp[i][j]$ 可由 $dp[i-1][j]$ 和 $dp[i][j-1]$ 转移过来;
因为 $(i,j)$ 可由 $(i-1,j)$ 和 $(i,j-1)$ 的末尾或开头插入 1 或 -1 得到,那到底是在开头插入还是结尾插入呢?
因为题意让求的是前缀最大值之和,所以,我们考虑到在开头插入 1 或 -1:
- 在 $(i-1,j)$ 的开头插入 1,也就意味着这 $C_{i+j-1}^{i-1}$ 个序列的前缀最大值都会增加 1,那么
- $dp[i][j] += dp[i-1][j]+C_{i+j-1}^{i-1}$
- 在 $(i,j-1)$ 的开头插入 -1,意味着这 $C_{i+j-1}^{i}$ 个序列的前缀最大值会减少 1,那么
- $dp[i][j] += dp[i][j-1]-C_{i+j-1}^{i}+h[i][j-1]$
$h[i][j-1]$ 是干啥用的呢?
由题意,前缀最大值最小为 0,所以,在 $(i,j-1)$ 的开头插入 -1 的时候,前缀最大值为 0 的序列是不会减少 1 的;
我们就需要将这些多减掉的 1 在加上;
定义 $h[i][j]$ 表示 $(i,j)$ 的 $C_{i+j}^{i}$ 个序列种前缀最大值为 0 的个数;
同样 $h[i][j]$ 可由 $h[i-1][j]$ 和 $h[i][j-1]$ 转移过来;
考虑到 $h[i][j]$ 的定义,我们这次选择在 $(i-1,j)$ 和 $(i,j-1)$ 的结尾插入 1 或 -1;
很容易想到,如果 $i > j$,一定有 $h[i][j]=0$,所以,我们考虑 $i \le j$ 的情况;
因为是在结尾插入的,所以,前缀最大值第一次出现的位置是不会改变的,所以有 $h[i][j]=h[i-1][j]+h[i][j-1]$;
•Code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn=2e3+;
const int MOD=; int n,m;
ll dp[maxn][maxn];
ll h[maxn][maxn];
ll C[*maxn][*maxn]; void Init()
{
C[][]=;
for(int i=;i < *maxn;++i)
for(int j=;j <= i;++j)
{
if(j == || j == i)
C[i][j]=;
else
C[i][j]=C[i-][j]+C[i-][j-];
C[i][j] %= MOD;
} mem(h,);
for(int j=;j < maxn;++j)
h[][j]=;
for(int i=;i < maxn;++i)
for(int j=i;j < maxn;++j)
h[i][j]=(h[i-][j]+h[i][j-])%MOD; dp[][]=;
for(int i=;i < maxn;++i)
dp[i][]=i;
for(int j=;j < maxn;++j)
dp[][j]=;
for(int i=;i < maxn;++i)
for(int j=;j < maxn;++j)
{
dp[i][j]=(dp[i-][j]+C[i+j-][j])+(dp[i][j-]-C[i+j-][i]+h[i][j-]);
dp[i][j]=(dp[i][j]+MOD)%MOD;
}
} int main()
{
Init();
scanf("%d%d",&n,&m);
printf("%lld\n",dp[n][m]); return ;
}
CodeForces 1204E"Natasha, Sasha and the Prefix Sums"(动态规划 or 组合数学--卡特兰数的应用)的更多相关文章
- CodeForces - 1204E Natasha, Sasha and the Prefix Sums (组合数学,卡特兰数扩展)
题意:求n个1,m个-1组成的所有序列中,最大前缀之和. 首先引出这样一个问题:使用n个左括号和m个右括号,组成的合法的括号匹配(每个右括号都有对应的左括号和它匹配)的数目是多少? 1.当n=m时,显 ...
- 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] ...
- [CF1204E]Natasha,Sasha and the Prefix Sums 题解
前言 本文中的排列指由n个1, m个-1构成的序列中的一种. 题目这么长不吐槽了,但是这确实是一道好题. 题解 DP题话不多说,直接状态/变量/转移. 状态 我们定义f表示"最大prefix ...
- 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 ...
- 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 ...
- CF1204E Natasha, Sasha and the Prefix Sums (卡塔兰数推理)
题面 题解 把题意变换一下,从(0,0)走到(n,m),每次只能网右或往上走,所以假设最大前缀和为f(n),那么走的时候就要到达但不超过 y = x-f(n) 这条线, 我们可以枚举答案,然后乘上方案 ...
- CodeForces 837F - Prefix Sums | Educational Codeforces Round 26
按tutorial打的我血崩,死活挂第四组- - 思路来自FXXL /* CodeForces 837F - Prefix Sums [ 二分,组合数 ] | Educational Codeforc ...
- Educational Codeforces Round 26 [ D. Round Subset ] [ E. Vasya's Function ] [ F. Prefix Sums ]
PROBLEM D - Round Subset 题 OvO http://codeforces.com/contest/837/problem/D 837D 解 DP, dp[i][j]代表已经选择 ...
- Codeforces 837F Prefix Sums
Prefix Sums 在 n >= 4时候直接暴力. n <= 4的时候二分加矩阵快速幂去check #include<bits/stdc++.h> #define LL l ...
随机推荐
- NOIP模拟 7.05
Problem 1 双色球(ball.cpp/c/pas) [题目描述] 机房来了新一届的学弟学妹,邪恶的chenzeyu97发现一位学弟与他同名,于是他当起了善良的学长233 “来来来,学弟,我考你 ...
- 洛谷 P1948 [USACO08JAN]电话线Telephone Lines 最短路+二分答案
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例 输出样例 说明 思路 AC代码 题面 题目链接 P1948 [USACO08JAN]电话线Telephone ...
- Liferay 7 module项目的依赖问题
build.gradle中的dependencies和bnd.bnd的Private-Package的关系是,build.gradle解决编译时候所需的所有依赖问题,但是这些依赖并不会被打包到buil ...
- 【POJ 3294】Life Forms
[链接]h在这里写链接 [题意] 给你n个字符串. 让你找最长的字符串s; 这个s在超过一半的子串里面都有出现过且长度大于n/2; 如果有多个,输出多行. (按字典序输出) 也没说会不会出现大写. [ ...
- PHP开发api接口安全验证的实例,值得一看
php的api接口 在实际工作中,使用PHP写api接口是经常做的,PHP写好接口后,前台就可以通过链接获取接口提供的数据,而返回的数据一般分为两种情况,xml和json,在这个过程中,服务器并不知道 ...
- MSSQL → 02:数据库结构
一.数据库的组成 在SQL Server 2008中,用户如何访问及使用数据库,就需要正确了解数据库中所有对象及其设置.数据库就像一个容器,它里面除了存放着数据的表之外,还有视图.存储过程.触发器.约 ...
- ListView组件中 onEndReached 方法在滚动到距离列表最底部一半时执行
初次使用ListView,在写列表滚动到最底部自动加载使用到方法onEndReached, 发现: ListView组件中 onEndReached 方法在滚动到距离列表最底部一半时执行, 于是翻看文 ...
- UVA_445:Marvelous Mazes
Language:C++ 4.8.2 #include<stdio.h> #include<string.h> #include<ctype.h> int main ...
- HTML5入门指南
1.HTML5到底是什么? HTML5是HTML最新的修订版本,2014年10月由万维网联盟(W3C)完成标准制定.目标是取代1999年所制定的HTML 4.01和XHTML 1.0标准,以期能在互联 ...
- 01-常见Dos命令、Java历史、Java跨平台、配置Path环境变量、第一个HelloWorld例子
常见Dos命令 dir: 列出当前目录下的文件以及文件夹 md: 创建目录 rd: 删除目录 cd: 进入指定目录 del: 删除文件 copy: 复制文件 xcopy: 复制目录 tree: 列出目 ...