Codeforces 295D - Greg and Caves(dp)
题意:
给出一个 \(n \times m\) 的矩阵,需对其进行黑白染色,使得以下条件成立:
- 存在区间 \([l,r]\)(\(1\leq l\leq r\leq n\)),使得第 \(l,l+1,\dots,r\) 行恰有 \(2\) 个格子染成黑色,其余行所有格子均为白色。
- 设第 \(i\) 行染黑的两个格子所在的列为 \(a_i,b_i(a_i\lt b_i)\),那么存在 \(l \leq t \leq r\),使得 \(a_l\geq a_{l+1}\geq a_{l+2}\geq\dots\geq a_t\leq a_{t+1}\leq a_{t+2}\leq\dots\leq a_r\),\(b_l\geq b_{l+1}\geq b_{l+2}\geq\dots\geq b_t\geq b_{t+1}\leq b_{t+2}\leq\dots\leq b_r\)。
\(n,m \in [1,2000]\)
答案对 \(10^9+7\) 取模。
很显然可以分上部分和下部分考虑,这里考虑上半部分。
设 \(dp_{i,j}\) 表示填好了 \(i\) 行,第 \(i\) 行的“宽度”(\(b_i-a_i+1\))为 \(j\)。
那么我们枚举上一行的宽度 \(k\),即 \(dp_{i,j}=\sum\limits_{k=2}^jdp_{i-1,k}\times(j-k+1)\)。
前缀和优化可以搞到 \(n^2\)。
然后我们考虑计算答案。
我们枚举上文中提到的 \(t\) 的位置,以及第 \(t\) 行的“宽度” \(w\),注意可能有多个 \(t\) 满足条件,这里我们枚举的是最下方的 \(t\),否则可能会重复计算。
这部分对答案的贡献为 \(f(t,w)=(\sum\limits_{i=1}^tdp_{i,w})\times(1+\sum\limits_{k=1}^{n-i}\sum\limits_{l=2}^{w-1}dp_{k,l}\times(w-l+1))\)
稍微解释一下这个式子。
前面的括号是填好上半部分的方案数,枚举行数求个和即可。
后面的括号的填好下半部分的方案数。第 \(t+1\) 行的宽度必然小于 \(w\),否则 \(t+1\) 也满足条件,我们枚举就不是“最下方的 \(t\)”了。
当然 \(t+1\) 行也可以不染色,贡献为 \(1\)。
预处理三个前缀和就可以 \(\mathcal O(1)\) 求出 \(f(t,w)\)。
最后 \(ans=\sum\limits_{t=1}^n\sum\limits_{w=2}^mf(t,w)\times(m-w+1)\)
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define fz(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a) a.begin(),a.end()
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,0x3f,sizeof(a))
#define y1 y1010101010101
#define y0 y0101010101010
typedef pair<int,int> pii;
typedef long long ll;
const ll MOD=1e9+7;
ll n,m,dp[2005][2005],s1[2005][2005],s2[2005][2005],s[2005][2005],_s[2005][2005],__s[2005][2005];
int main(){
scanf("%d%d",&n,&m);
for(int i=2;i<=m;i++) dp[1][i]=1;
for(int j=2;j<=m;j++){
s1[1][j]=(s1[1][j-1]+dp[1][j])%MOD;
s2[1][j]=(s2[1][j-1]+dp[1][j]*j%MOD)%MOD;
}
for(int i=2;i<=n;i++){
for(int j=2;j<=m;j++){
dp[i][j]=(-s2[i-1][j]+s1[i-1][j]*(j+1)%MOD+MOD)%MOD;
// printf("%d %d %lld\n",i,j,dp[i][j]);
}
for(int j=2;j<=m;j++){
s1[i][j]=(s1[i][j-1]+dp[i][j])%MOD;
s2[i][j]=(s2[i][j-1]+dp[i][j]*j%MOD)%MOD;
}
}
ll ans=0;
for(int i=1;i<=n;i++) for(int j=2;j<=m;j++) s[i][j]=(s[i-1][j]+dp[i][j])%MOD;
for(int i=1;i<=n;i++) for(int j=2;j<=m;j++) _s[i][j]=(_s[i][j-1]+s[i][j])%MOD;
for(int i=1;i<=n;i++) for(int j=2;j<=m;j++) __s[i][j]=(__s[i][j-1]+s[i][j]*j%MOD)%MOD;
for(int i=1;i<=n;i++) for(int j=2;j<=m;j++){
ans=(ans+s[i][j]*(_s[n-i][j-1]*(j+1)%MOD-__s[n-i][j-1]+MOD+1)%MOD*(m-j+1)%MOD)%MOD;
// printf("%d %d %lld\n",i,j,s[i][j]*(_s[n-i][j-1]*(j+1)%MOD-__s[n-i][j-1]+MOD+1)%MOD*(m-j+1)%MOD);
}
printf("%lld\n",ans);
return 0;
}
/*
dp[i][j]=\sum dp[i-1][k]*(j-k+1)
\sum s[x][k]*(j-k+1)
*/
Codeforces 295D - Greg and Caves(dp)的更多相关文章
- CodeForces - 710E Generate a String (dp)
题意:构造一个由a组成的串,如果插入或删除一个a,花费时间x,如果使当前串长度加倍,花费时间y,问要构造一个长度为n的串,最少花费多长时间. 分析:dp[i]---构造长度为i的串需要花费的最短时间. ...
- [CodeForces - 296D]Greg and Graph(floyd)
Description 题意:给定一个有向图,一共有N个点,给邻接矩阵.依次去掉N个节点,每一次去掉一个节点的同时,将其直接与当前节点相连的边和当前节点连出的边都需要去除,输出N个数,表示去掉当前节点 ...
- Educational Codeforces Round 51 D. Bicolorings(dp)
https://codeforces.com/contest/1051/problem/D 题意 一个2*n的矩阵,你可以用黑白格子去填充他,求联通块数目等于k的方案数,答案%998244353. 思 ...
- Codeforces 536D - Tavas in Kansas(dp)
Codeforces 题目传送门 & 洛谷题目传送门 其实这题本该 2019 年 12 月就 AC 的(详情请见 ycx 发此题题解的时间),然鹅鸽到了现在-- 首先以 \(s,t\) 分别为 ...
- Codeforces 467C George and Job(DP)
题目 Source http://codeforces.com/contest/467/problem/C Description The new ITone 6 has been released ...
- Codeforces A ACM (ACronym Maker) (dp)
http://codeforces.com/gym/100650 概要:给出一个缩写,和一些单词,从单词中按顺序选一些字母作为缩写,问方案数. 限制:某些单词要忽略,每个单词至少要选一个字母. dp[ ...
- codeforces 813 D. Two Melodies(dp)
题目链接:http://codeforces.com/contest/813/problem/D 题意:求两个不相交的子集长度之和最大是多少,能放入同一子集的条件是首先顺序不能变,然后每一个相邻的要么 ...
- codeforces 762 D. Maximum path(dp)
题目链接:http://codeforces.com/problemset/problem/762/D 题意:给出一个3*n的矩阵然后问从左上角到右下角最大权值是多少,而且每一个点可以走上下左右,但是 ...
- CodeForces - 446A DZY Loves Sequences(dp)
题意:给定一个序列a,求最长的连续子序列b的长度,在至多修改b内一个数字(可修改为任何数字)的条件下,使得b严格递增. 分析: 1.因为至多修改一个数字,假设修改a[i], 2.若能使a[i] < ...
随机推荐
- 时间轮机制在Redisson分布式锁中的实际应用以及时间轮源码分析
本篇文章主要基于Redisson中实现的分布式锁机制继续进行展开,分析Redisson中的时间轮机制. 在前面分析的Redisson的分布式锁实现中,有一个Watch Dog机制来对锁键进行续约,代码 ...
- Python绘制Excel图表
今天讲解下如何使用Python绘制各种Excel图表,下面我们以绘制饼状图.柱状图.水平图.气泡图.2D面积图.3D面积图为例来说明. import openpyxlfrom openpyxl imp ...
- Bubble和BubbleButton气泡框
from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.lang.builder import Buil ...
- 关于STM32 (Cortex-M3) 中NVIC的分析
一.STM32 (Cortex-M3) 中的优先级概念 STM32(Cortex-M3)中有两个优先级的概念:抢占式优先级和响应优先级,也把响应优先级称作"亚优先级"或" ...
- matplotlib散点图
我们常用的统计图如下: 1.学会绘制散点图 一个小demo: 假设通过爬虫你获取到了北京2016年3,10月份每天白天的最高气温(分别位于列表a,b),那么此时如何寻找出气温和随时间(天)变化的某种规 ...
- Go语言核心36讲(Go语言进阶技术十一)--学习笔记
17 | go语句及其执行规则(下) 知识扩展 问题 1:怎样才能让主 goroutine 等待其他 goroutine? 我刚才说过,一旦主 goroutine 中的代码执行完毕,当前的 Go 程序 ...
- uni-app(Vue)中(picker)用联动(关联)选择以至于完成某些功能
如下图所示,在项目中需求是通过首先选择学生的专业,选好之后在每个专业下面选择对应的学期,每个学期有对应的学费,因此就需要联动选择来实现这一功能. 以下仅展示此功能主要代码: <div class ...
- shell 脚本静默安装oracle11g
以下脚本的手动安装连接: https://www.cnblogs.com/leihongnu/p/12698593.html [ #/bin/bash#安装日志touch /root/message ...
- .NET 生态系统的蜕变之 .NET 6云原生
云原生的英文名是cloud native,native 就是土著的意思,也就是土著对当地的环境是非常适应的,在云的环境和传统的数据中心是非常不同的,云原生就是要用的云的技术来构建应用, 利用云的技术来 ...
- Java不同时区(timezone)之间时间转换
最近出现一个问题是这样的:我们的系统在国外打印的日志时间由于时差关系和国内不一致,看起来不方便,希望国外的日志和国内保持一致,即:需要对不同时区的时间做转换调整,统一为国内时间. 一.关于时区的一些概 ...