⭐ 数组切分
输入
4
1 3 2 4
输出
5
⭐ 区间最大值 - 区间最小值 == 区间长度:说明该区间为连续的自然数
🤠 暴馊dfs (过 50 % 的案例)
import java.util.*;
public class Main
{
static int mod = 1000000007, n;
static int res = 0;
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++)
{
a[i] = sc.nextInt();
}
dfs(a, 0);
System.out.println(res % mod);
}
// sta 表示当前搜索到的下标
private static void dfs(int[] a, int sta)
{
// 搜完啦
if (sta == n)
{
res++;
return;
}
for (int i = sta; i < n; i++)// 从区间起点开始,枚举每一个区间终点
{
if (check(a, sta, i))//
{
dfs(a, i + 1);
}
}
}
private static boolean check(int[] a, int l, int r)
{
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for (int i = l; i <= r; i++)
{
if (a[i] > max)
max = a[i];
if (a[i] < min)
min = a[i];
}
return max - min == r - l;
}
}
⭐ 思路
第一层循环是i,从1到n枚举每个元素;
第二层循环是j,从i逆序枚举每个(j ~ i)的区间。
🤠 DP代码
import java.util.Scanner;
public class Main
{
static int mod = 1000000007;
static int res = 0;
static int[] f, a;
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
a = new int[n + 1];
f = new int[n + 1];
for (int i = 1; i <= n; i++)//下标从1开始
a[i] = sc.nextInt();
f[0] = 1;
for (int i = 1; i <= n; i++)//枚举区间终点
{
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int j = i; j > 0; j--)//枚举最后一个区间的起点
{
min = Math.min(min, a[j]);
max = Math.max(max, a[j]);
if (i - j == max - min)
f[i] = (f[i] + f[j - 1]) % mod;
}
}
System.out.println(f[n]);
}
}