CF1503E 2-Coloring
CF1503E 2-Coloring
cjx 组合强。
思路
观察一下题目,不难发现只有当黄色形成如下的单峰时才合法。
(染错色了,将就一下)
其中两座峰的峰顶高度相加等于 \(m\),为了方便统计,我们钦定右边的峰一定在左峰下方的行出现,最后答案乘以二就是最终方案。
发现对于每一边是两个最长不下降子序列拼在一起。
设 \(f[i][j]\) 为长度为 \(i\) 的最长不下降子序列,最高点高度为 \(j\) 的方案数。
再设 \(f'[i][j]\) 为长度为 \(i\) 的最长不下降子序列,仅有一个最高点为 \(j\) 的方案数。
答案就是
\]
相当于枚举第一个峰在行 \(i\),第二个峰在行 \(j\),第一个峰高度为 \(k\)。
变幻一下:
\]
这样给后一个和式做一个后缀和优化,即可把复杂度优化到 \(O(n^2)\) 级别。
当然有例外是这个样子。
两峰交在一起(必须保证在连续的行且峰顶高度相加大于 \(m\)),也是一种方案。
\]
相当于枚举左边的峰顶在行 \(i\),左峰高度为 \(x\),右峰高度为 \(y\),同时求和了峰过后的一段不下降子序列的方案。
\]
对于 \(\sum_{k=1}^{x-1}f[i][k]\) 和 \(\sum_{k=1}^{y-1} f[n-i][k]\) 前缀和优化。
然后预处理出所有的
\]
再次前缀和。
即可在 \(O(n^2)\) 的时间内求出上述和式。
对于 \(f\) 和 \(f'\) 的转移是容易的。
\]
\]
初始值 \(f[0][0]=1\)。
其实你看到这里,已经可以使用 dp 做出本题了,但是如果你想进一步了解组合,请移步。
不难发现,我们每次的转移都相当于求一次前缀和,而 \(f[0][0]=1\)。
所以有可以构造这样的生成函数:
\]
观察 \(\sum_{i=0} x^i\) 的优雅性质,你会发现 \(1\times \sum_{i=0} x^i\) 相当于求一次前缀和。
而 \((\sum_{i=0} x^i)^2\) 相当于求两次前缀和(\(x^i\) 的系数是第 \(i\) 项的求前缀和后的值)。
由 \(f[0]\) 转移到 \(f[1]\) 的过程相当于乘以 \(\sum_{i=0} x^i\)(一次前缀和),所以有:
\]
推广一下,每次 \(f[i]\) 向 \(f[i+1]\) 的转移都是乘以 \(\sum_{i=0} x^i\)(每转移一次求一次前缀和),所以有:
\]
对于 \(\sum_{i=0} x^i\),的封闭形式为 \((1-x)^{-1}\) 有很多种方法求,这里不再赘述。
所以有:
\]
使用广义二项式展开 \((1+(-x))^{-i}\),即可得到第 \(j\) 项的系数为:
\]
关于牛顿二项式系数,已经有完备的公式,本处直接套公式即可,故不再展开讨论。
把系数乘上 \((-x)^j\),有
\]
从比较简单的组合意义考虑,有 \(j\) 个球,有 \(i-1\) 个挡板,可以为空,两个挡板之间的球数相当于相邻两项的差。
那么有:
\]
在观察一下 \(f'\) 求值的式子,你会发现 \(f'[i][j]=f[i][j-1]\)。
所以其实你也求出 \(f'\) 的组合意义了。
相当于有 \(j\) 个球,\(i-1\) 个挡板,最后一个挡板至少挡一个球,那么就可以投入 \(j-1\) 个球供所有挡板挡。
\]
如果考虑生成函数的话,\(f'[i][j]\) 相当于较 \(f[i][j]\) 向后平移了一个位置,那么可以写成:
\]
或
\]
于是你就可以 愉快 的 AC 本题了。
CODE
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 5000
#define mod 998244353
const int maxn=5e3+5;
ll n,m,ans;
ll fac[maxn],inv[maxn],f[maxn];
inline ll ksm(ll x,ll y)
{
ll sum=1;
for(;y;y/=2,x=x*x%mod) if(y&1) sum=sum*x%mod;
return sum;
}
inline ll C(int n,int m)
{
if(n<m||m<0) return 0;
return 1ll*fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int main()
{
freopen("magic.in","r",stdin);
freopen("magic.out","w",stdout);
for(int i=fac[0]=1;i<=N;i++) fac[i]=fac[i-1]*i%mod;
inv[N]=ksm(fac[N],mod-2);
for(int i=N-1;~i;i--) inv[i]=inv[i+1]*(i+1)%mod;
scanf("%lld%lld",&n,&m);
for(int h=1;h<n;h++)
{
for(int j=m;j>=2;j--)
{
f[j]=(1LL*f[j+1]+1LL*C(j+n-h-2,n-h-1)*C(m-j+n-h,n-h)%mod)%mod;
}
for(int i=m-1;i>=1;i--)
{
ans = (1LL*ans+1LL*C(i+h-1,h)*C(m-i+1+h-2,h-1)%mod*f[i+1]%mod)%mod;
}
}
memset(f,0,sizeof(f));
for(int x=1;x<=m;x++)
{
for(int j=n-1;j>=1;j--)
{
f[j]=(1LL*f[j+1]+1LL*C(m-x+n-j-1,n-j-1)*C(m-x+j-1,j)%mod)%mod;
}
for(int i=1;i<n;i++)
{
ans=(1LL*ans+1LL*C(x+i-1,i)*C(x+n-i-1,n-i-1)%mod*f[n-i+1]%mod)%mod;
}
}
printf("%lld\n",ans*2%mod);
}
CF1503E 2-Coloring的更多相关文章
- Codeforces Round #369 (Div. 2)---C - Coloring Trees (很妙的DP题)
题目链接 http://codeforces.com/contest/711/problem/C Description ZS the Coder and Chris the Baboon has a ...
- CF149D. Coloring Brackets[区间DP !]
题意:给括号匹配涂色,红色蓝色或不涂,要求见原题,求方案数 区间DP 用栈先处理匹配 f[i][j][0/1/2][0/1/2]表示i到ji涂色和j涂色的方案数 l和r匹配的话,转移到(l+1,r-1 ...
- Codeforces Round #369 (Div. 2) C. Coloring Trees DP
C. Coloring Trees ZS the Coder and Chris the Baboon has arrived at Udayland! They walked in the pa ...
- CodeForces #369 C. Coloring Trees DP
题目链接:C. Coloring Trees 题意:给出n棵树的颜色,有些树被染了,有些没有.现在让你把没被染色的树染色.使得beauty = k.问,最少使用的颜料是多少. K:连续的颜色为一组 ...
- CodeForces 149D Coloring Brackets
Coloring Brackets time limit per test: 2 seconds memory limit per test: 256 megabytes input: standar ...
- C. Coloring Trees DP
传送门:http://codeforces.com/problemset/problem/711/C 题目: C. Coloring Trees time limit per test 2 secon ...
- codeforces 711C C. Coloring Trees(dp)
题目链接: C. Coloring Trees time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- POJ 1419 Graph Coloring(最大独立集/补图的最大团)
Graph Coloring Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 4893 Accepted: 2271 ...
- URAL 1080 Map Coloring(染色)
Map Coloring Time limit: 1.0 secondMemory limit: 64 MB We consider a geographical map with N countri ...
- POJ1419 Graph Coloring(最大独立集)(最大团)
Graph Coloring Time Limit: 1000MS Memor ...
随机推荐
- MSYS2、MinGW、Cygwin 关系梳理
还记得大一刚开始写 C 代码时,经常看到 MSYS2.MinGW.Cygwin 等名词.对于第一次接触编程的我来说这些名词让我眼花缭乱.当时查阅了一些资料,但是对于这些名词的解释始终让我云里雾里.现在 ...
- Mac 删除 Steam 游戏图标
Steam 将游戏安装在了 ~/Applications,打开访达,前往该目录,将相关游戏移到废纸篓.
- 【Java】之获取CSV文件数据以及获取Excel文件数据
一.获取CSV文件数据 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Sheet; impor ...
- sublime text2自动编译编译less文件为css,并让less文件高亮的两种方法
方法一:通过命令安装 1.打开sublime,ctrl+shift+p打开命令面板,找到package control:install Package,然后选择less2css,回车.2.继续ctrl ...
- 加快 hdfs block 块复制的参数调整
共涉及三个参数: dfs.namenode.replication.max-streams 30 => 70 dfs.namenode.replication.max-streams-hard- ...
- Maven 使用方法
Maven Maven是一个项目管理工具,它包含了一个项目对象模型(POM:Project Object Model),其表现于一个XML文件(pom.xml),其中包含了项目的基本学习,依赖关系,插 ...
- 如何创建一个Java游戏客户端
创建一个完整的Java游戏客户端示例是一个相对复杂的任务,因为它通常涉及图形用户界面(GUI).事件处理.游戏逻辑等多个方面.为了简化,我将提供一个基于Java Swing的简单游戏客户端示例:一个简 ...
- [32](CSP 集训) CSP-S 模拟 3
A 奇观 考虑到 CCF 可以拆开算,答案为 \((ans_c)^2\times ans_f\) 剩下的东西比较少,考虑 DP 我的 dp 是从爆搜改的,设 \(f_{i,j}\) 表示递归到第 \( ...
- 致敬传奇 Kruskal 重构树题硬控我三小时
NOI2018 归程 存边的数组拿来干两件事,忘了清空了,其实最好开两个的 dfs 没开 vis 导致不知道为什么出现的绕圈 倍增的 fa[i][j] 定义的时候前面是 \(2^{i}\) 写着写着记 ...
- Kubernetes Pod原理(十六)
一.Pod Kubernetes 最基本的调度单元 前面我们了解了 Kubernetes 的基本架构,以及如何使用资源清单在集群中部署一个应用.我们也了解到了 Pod 是 Kubernetes 集群中 ...