目录

1.数组切分

1.问题描述

已知一个长度为 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_数据结构 的数组: 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_蓝桥杯_02 恰好是 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_蓝桥杯_03 的一个排列。现在要求你将 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_职场和发展_04 数组切分成若干个 (最少一个, 最多 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_数据结构

例如对于 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_职场和发展_06, 一共有 5 种切分方法:

第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_数据结构_07

第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_数据结构_08 包含 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_动态规划_09第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_职场和发展_10 , 是 一段连续的自然数, 另外 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_数据结构_11第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_蓝桥杯_12

第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_数据结构_13 包含 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_动态规划_09第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_职场和发展_15 , 是一段连续的自然数, 另外 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_数据结构_11

第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_动态规划_17 包含 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_职场和发展_18第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_职场和发展_10 , 是 一段连续的自然数, 另外 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_蓝桥杯_12

第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_算法_21 : 只有一个子数组, 包含 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_职场和发展_18第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_职场和发展_15

2.输入格式

第一行包含一个整数 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_数据结构 。第二行包含 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_数据结构 个整数, 代表 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_职场和发展_04

3.输出格式

输出一个整数表示答案。由于答案可能很大, 所以输出其对 ​​1000000007​​ 取模后的值

4.样例输入

4
1 3 2 4

5.样例输出

5

6.数据范围

对于 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_算法_27 评测用例, 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_数据结构_28.

对于 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_蓝桥杯_29 评测用例, 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_数据结构_30.

7.原题连接

​数组切分​

2.解题思路

一道比较明显的​​dp​​​题,首先考虑一段子数组在包含一段连续的自然数时,会有什么性质?设区间第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_算法_31的值域为第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_算法_32,不难发现如果该区间是一段连续自然数时,将会满足:
第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_动态规划_33
也就是区间的最大值减去最小值等于右端下标减去左端下标。有了这个性质以后,从数据范围考虑,第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_算法_34 最多为 ​​​1e4​​​ ,说明我们可以进行一个 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_动态规划_35第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_算法_36 转移。
第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_动态规划_37 为只考虑前 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_职场和发展_38 个数能切分的情况数。当区间第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_数据结构_39是一段连续自然数时,我们可以进行状态转移第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_蓝桥杯_40
对于每个 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_职场和发展_38 我们可以从倒着遍历回去一直到下标 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_职场和发展_18 ,同时开两个变量维护已遍历的数中的最大值和最小值,当此时区间是一段连续自然数时我们可以进行一次转移。
初始化时应该置 第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_蓝桥杯_43
整体时间复杂度:第十三届蓝桥杯JavaB组省赛G题——数组切分 (AC)_蓝桥杯_44

模板代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 1000000007;
const int N=200010;

int n;
int a[N];
LL f[N];
void solve()
{
cin>>n;
for(int i=1;i<=n;++i) cin>>a[i];
f[0]=1;
for(int i=1;i<=n;++i){
int mx=a[i],mi=a[i];
for(int j=i;j>=1;j--){
mx=max(mx,a[j]);
mi=min(mi,a[j]);
if(mx-mi==i-j){
f[i]=(f[i]+f[j-1])%mod;
}
}
}
cout<<f[n]<<'\n';
}
int main()
{
ios_base :: sync_with_stdio(false);
cin.tie(nullptr);
solve();
return 0;
}