补一篇题解。
首先dp[i][j]:表示前i个数,以a[j]结尾的所有方案数量。
那么,我们首先按照...j < i...j=i...j > i三个分类讨论,然后再按照上一维的状态dp[i - 1][x]转移。
1. j < i
那么x的范围应该满足x <= j && a[x] <= a[j]。如何理解呢?会发现,只有这种情况,dp[i - 1][x]的数量才是全的。比如,如果x > j && x < i,a[x] <= a[j],此时的dp[i - 1][x]最后一部分已经是a[x]了,那么如果我们想要转移到dp[i][j],就肯定要把从j开始的一段全部变为a[j],但是会将a[i - 1] -> a[j],可以发现,此时我们假设的x其实已经变成了另外一个数了,那么状态都不对,则对应的方案数肯定也不对。差不多不合法的方案原因类似。
2. j = i
3. j > i
#include <bits/stdc++.h>
#define LL long long
#define int LL
#define INF 0x3f3f3f3f
#define PII pair<int,int>
#define pcc pair<char,char>
#define x first
#define y second
#define inf 1e18
#define kanm7 ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'
using namespace std;
const int N = 3010, mod = 1e9 + 7;
int dp[N][N], l[N], r[N];
int n;
void solve() {
cin >> n;
vector<int> a(n + 10);
for(int i = 1; i <= n; i ++) cin >> a[i];
for(int i = 1; i <= n; i ++) {
l[i] = 0, r[i] = n + 1;
for(int j = i; j; j --) {
if(a[j] < a[i]) {
l[i] = j;
break;
}
}
for(int j = i; j <= n; j ++) {
if(a[j] < a[i]) {
r[i] = j;
break;
}
}
// cout << i << ' ' << l[i] << ' ' << r[i] << endl;
}
for(int i = 1; i <= n; i ++) {
if(l[i] < 1) {
dp[1][i] = 1;
// cout << i << endl;
}
}
for(int i = 2; i <= n; i ++) {
for(int j = 1; j <= n; j ++) {
if(j < i) {
if(l[j] < i && i < r[j]) {
for(int x = 1; x <= n; x ++) {
if(x <= j && a[x] <= a[j]) {
dp[i][j] += dp[i - 1][x];
// cout << 1 << ' ' << j << ' ' << x << ' ' << dp[i - 1][x] << endl;
dp[i][j] %= mod;
}
}
}
}
if(j == i) {
if(l[j] < i && i < r[j]) {
for(int x = 1; x <= n; x ++) {
if(x <= i) {
dp[i][j] += dp[i - 1][x];
// cout << 2 << ' ' << j << ' ' << x << ' ' << dp[i - 1][x] << endl;
dp[i][j] %= mod;
}
}
}
}
if(j > i) {
if(l[j] < i && i < r[j]) {
for(int x = 1; x <= n; x ++) {
if(x <= i) {
dp[i][j] += dp[i - 1][x];
dp[i][j] %= mod;
} else if(x <= j && a[x] >= a[j]) {
dp[i][j] += dp[i - 1][x];
dp[i][j] %= mod;
}
}
}
}
}
}
int ans = 0;
for(int i = 1; i <= n; i ++) {
ans += dp[n][i];
// cout << i << ' ' << dp[n][i] << endl;
ans %= mod;
}
cout << ans << endl;
}
signed main() {
kanm7;
int T = 1;
// cin >> T;
while(T --) {
solve();
}
return 0;
}