题面

n

n

n 棵树排成一排,每棵树高度为

h

i

(

i

[

1

,

n

]

)

h_i~(i\in[1,n])

hi​ (i∈[1,n]) ,你现在要按照一个排列

P

P

P 的顺序去砍树,每砍一棵树,这棵树的高度就会变成

0

0

0 ,也就是说,砍一棵树

i

i

i 会使得

h

i

0

h_i\rightarrow0

hi​→0 。由于光头强的阻挠,你每次砍树的代价是当前这棵树相邻两棵树的高度加上这棵树的高度,即

h

i

1

+

h

i

+

h

i

+

1

h_{i-1}+h_i+h_{i+1}

hi−1​+hi​+hi+1​ 。

求有多少种不同的排列

P

P

P 能保证总代价最小,取模

998

244

353

998\,244\,353

998244353。

1

n

4000

,

1

h

i

1

0

9

1\leq n\leq4000,1\leq h_i\leq10^9

1≤n≤4000,1≤hi​≤109 .

题解

我们把排列投射到这一排树上,每个位置记录自己被砍的次序

p

i

p_i

pi​ 。

那么除了自己被砍时被算进去的代价,额外代价(因砍伐邻居而付出的代价)就可以用

p

p

p 来判断。对于每个

i

[

1

,

n

)

i\in[1,n)

i∈[1,n) ,若

p

i

<

p

i

+

1

p_i<p_{i+1}

pi​<pi+1​ ,则额外代价加上

h

i

+

1

h_{i+1}

hi+1​ ,若

p

i

>

p

i

+

1

p_i>p_{i+1}

pi​>pi+1​ 则额外代价加上

h

i

h_i

hi​ 。

现在我们看看,该怎么安排

p

i

p_i

pi​ ,使得总代价最小呢?

对于每个

i

[

1

,

n

)

i\in[1,n)

i∈[1,n) ,如果

h

i

<

h

i

+

1

h_i<h_{i+1}

hi​<hi+1​ ,那么限制

p

i

>

p

i

+

1

p_i>p_{i+1}

pi​>pi+1​ ;如果

h

i

>

h

i

+

1

h_i>h_{i+1}

hi​>hi+1​ ,那么限制

p

i

<

p

i

+

1

p_i<p_{i+1}

pi​<pi+1​ 。如果

h

i

=

h

i

+

1

h_i=h_{i+1}

hi​=hi+1​ ,相对大小无所谓了,不限制。这样下来,排列

p

p

p 就能使得总代价最小,满足所有限制条件的排列

p

p

p 的个数就是答案了。


那么就是一个经典问题:限制一个排列

p

p

p 相邻两位的大小关系,问总的排列个数。

如果是

n

1

0

5

n\leq10^5

n≤105 级别的数据,要用比较复杂难懂的容斥来做,假定一段同向,然后减去不合法。

可喜(惜)的是,这道题

n

4000

n\leq4000

n≤4000 ,可以

Θ

(

n

2

)

\Theta(n^2)

Θ(n2) 做。我们定义一个简单的

D

P

\rm DP

DP ,令

d

p

[

i

]

[

j

]

dp[i][j]

dp[i][j] 表示安排到第

i

i

i 位,前面有

j

j

j 个数比

p

i

p_i

pi​ 小的方案数。转移如下:

  • p

    i

    >

    p

    i

    1

    p_i>p_{i-1}

    pi​>pi−1​ :

    d

    p

    [

    i

    ]

    [

    j

    ]

    =

    k

    =

    0

    j

    1

    d

    p

    [

    i

    1

    ]

    [

    k

    ]

    dp[i][j]=\sum_{k=0}^{j-1}dp[i-1][k]

    dp[i][j]=∑k=0j−1​dp[i−1][k]

  • p

    i

    <

    p

    i

    1

    p_i<p_{i-1}

    pi​<pi−1​ :

    d

    p

    [

    i

    ]

    [

    j

    ]

    =

    k

    =

    j

    i

    2

    d

    p

    [

    i

    1

    ]

    [

    k

    ]

    dp[i][j]=\sum_{k=j}^{i-2}dp[i-1][k]

    dp[i][j]=∑k=ji−2​dp[i−1][k]

  • (

    e

    m

    p

    t

    y

    )

    ({\rm empty})

    (empty) :

    d

    p

    [

    i

    ]

    [

    j

    ]

    =

    k

    =

    0

    i

    2

    d

    p

    [

    i

    1

    ]

    [

    k

    ]

    dp[i][j]=\sum_{k=0}^{i-2}dp[i-1][k]

    dp[i][j]=∑k=0i−2​dp[i−1][k]

裸的前缀和优化,复杂度

Θ

(

n

2

)

\Theta(n^2)

Θ(n2) 。

CODE

#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 4005
#define LL long long
#define DB double
#define lowbit(x) (-(x) & (x))
#define ENDL putchar('\n')
LL read() {
LL f=1,x=0; char s = getchar();
while(s < '0' || s > '9') {if(s == '-')f = -f;s = getchar();}
while(s >= '0' && s <= '9') {x=x*10 + (s-'0');s = getchar();}
return x * f;
}
const int MOD = 1000000007;
int n,m,i,j,s,o,k;
int a[MAXN];
int dp[MAXN][MAXN];
int sum[MAXN][MAXN],suf[MAXN][MAXN];
int main() {
n = read();
for(int i = 1;i <= n;i ++) {
a[i] = read();
}
dp[0][0] = 1;
sum[0][0] = suf[0][0] = 1;
for(int i = 1;i <= n;i ++) {
for(int j = 0;j < i;j ++) {
if(a[i] > a[i-1]) {
dp[i][j] = suf[i-1][j];
}
else if(a[i] < a[i-1]) {
if(j > 0) dp[i][j] = sum[i-1][j-1];
}
else dp[i][j] = suf[i-1][0];
}
sum[i][0] = dp[i][0];
suf[i][i-1] = dp[i][i-1];
for(int j = 1;j < i;j ++) sum[i][j] = (sum[i][j-1] + dp[i][j]) % MOD;
for(int j = i-2;j >= 0;j --) suf[i][j] = (suf[i][j+1] + dp[i][j]) % MOD;
}
int ans = suf[n][0];
printf("%d\n",ans);
return 0;
}

ABC209F. Deforestation——DP(、数学容斥)的更多相关文章

  1. 青云的机房组网方案(简单+普通+困难)(虚树+树形DP+容斥)

    题目链接 1.对于简单的版本n<=500, ai<=50 直接暴力枚举两个点x,y,dfs求x与y的距离. 2.对于普通难度n<=10000,ai<=500 普通难度解法挺多 ...

  2. bzoj3622已经没有什么好害怕的了 dp+组合+容斥(?)

    3622: 已经没有什么好害怕的了 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1033  Solved: 480[Submit][Status][ ...

  3. [UOJ422][集训队作业2018]小Z的礼物——轮廓线DP+min-max容斥

    题目链接: [集训队作业2018]小Z的礼物 题目要求的就是最后一个喜欢的物品的期望得到时间. 根据$min-max$容斥可以知道$E(max(S))=\sum\limits_{T\subseteq ...

  4. BZOJ4361 isn 树状数组、DP、容斥

    传送门 不考虑成为非降序列后停止的限制,那么答案显然是\(\sum\limits_{i=1}^N cnt_i \times (N-i)!\),其中\(cnt_i\)表示长度为\(i\)的非降序列数量 ...

  5. 洛谷P4859 已经没有什么好害怕的了 [DP,容斥]

    传送门 思路 大佬都说这是套路题--嘤嘤嘤我又被吊打了\(Q\omega Q\) 显然,这题是要\(DP\)的. 首先思考一下性质: 为了方便,下面令\(k=\frac{n+k}{2}\),即有恰好\ ...

  6. CodeForces - 285E: Positions in Permutations(DP+组合数+容斥)

    Permutation p is an ordered set of integers p1,  p2,  ...,  pn, consisting of n distinct positive in ...

  7. 【HDOJ5519】Kykneion asma(状压DP,容斥)

    题意:给定n和a[i](i=0..4),求所有n位5进制数中没有前导0且i出现的次数不超过a[i]的数的个数 2<=n<=15000,0<=a[i]<=3e4 思路:设f(n, ...

  8. loj#2542. 「PKUWC2018」随机游走(树形dp+Min-Max容斥)

    传送门 首先,关于\(Min-Max\)容斥 设\(S\)为一个点的集合,每个点的权值为走到这个点的期望时间,则\(Max(S)\)即为走遍这个集合所有点的期望时间,\(Min(S)\)即为第一次走到 ...

  9. LOJ3102. 「JSOI2019」神经网络 [DP,容斥,生成函数]

    传送门 思路 大部分是感性理解,不保证完全正确. 不能算是神仙题,但我还是不会qwq 这题显然就是求:把每一棵树分成若干条链,然后把链拼成一个环,使得相邻的链不来自同一棵树,的方案数.(我才不告诉你们 ...

随机推荐

  1. Linux Cgroup v1(中文翻译)(3):CPU Accounting Controller

    英文原文: https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/cpuacct.html CPU Accounting Contr ...

  2. Java 基础常见知识点&面试题总结(上),2022 最新版!| JavaGuide

    你好,我是 Guide.秋招即将到来,我对 JavaGuide 的内容进行了重构完善,公众号同步一下最新更新,希望能够帮助你. 基础概念与常识 Java 语言有哪些特点? 简单易学: 面向对象(封装, ...

  3. camunda如何调用HTTP REST(Service Task)服务节点

    ​ Camunda中的Service Task(服务任务)用于调用服务.在Camunda中,可以通过调用本地Java代码.外部工作项.web服务形式实现的逻辑来完成的. 本文重点描述如何使用web服务 ...

  4. 《SQL Server基础——SQL语句》

    SQL Server基础--SQL语句       一.创建和删除数据库: 1.创建数据库(默认化初始值) 格式: CREATE DATABASE 数据库名称 例如: CREATE DATABASE ...

  5. Acwing785.快速排序

    Acwing785.快速排序 快排模板: y总教学大法好~: #include <iostream> using namespace std; const int N = 1000010; ...

  6. 关于Vue 移动端适配 (px2rem 插件将px转为rem)

    一.安装 npm install px2rem-loader lib-flexible --save 二.入口文件main.js加上 import 'lib-flexible/flexible.js' ...

  7. ms12-020漏洞

    一.环境说明 kali linux windows 7 sp1 二.ms12-020漏洞利用 msf5 exploit(windows/browser/ms10_002_aurora) > se ...

  8. js烧脑面试题大赏

    本文精选了20多道具有一定迷惑性的js题,主要考察的是类型判断.作用域.this指向.原型.事件循环等知识点,每道题都配有笔者详细傻瓜式的解析,偏向于初学者,大佬请随意. 第1题 let a = 1 ...

  9. Python实现12种概率分布(附代码)

    今天给大家带来的这篇文章是关于机器学习的,机器学习有其独特的数学基础,我们用微积分来处理变化无限小的函数,并计算它们的变化:我们使用线性代数来处理计算过程:我们还用概率论与统计学建模不确定性. 在这其 ...

  10. 使用C#编程语言开发Windows Service服务

    转载-https://www.cnblogs.com/yubao/p/8443455.html Create Windows Service project using Visual Studio C ...