题意以及判断
连续子数组,这是重点哈,连续子数组我总结了以下几个性质:
1. 两层for可以枚举所有的连续子数组,也可以dfs,看情况吧,如果是dfs可能会爆栈。
2. 乘法性质:
比如:[1,2,3,4,5],元素1所在的连续子数组的数量有1*5。2所在的子数组数量有2*4=8,自己算算找规律。
如何判断子数组内部连续?
1. 可以先排序,然后在循环判断,大概O(logk+k) ,1 <= k <= n
2. 公差为1情况下,如果等差数列长度为n,那么会有一个结论,既max - min = n - 1,O(1)时间判断等差数列。
3. 求和公式 a1*n + n * (n-1) /2 ,也是O(1)时间复杂度。
dfs 骗分
这里我们只拿前30%,骗一下分, 剩下的给随机数看老天爷吧。
import java.util.Random;
import java.util.Scanner;
public class Main {
static int N, MOD = (int)1e9+7;
static int[] arrays;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
N = scan.nextInt();
arrays = new int[N];
for (int i = 0; i < N; i++) {
arrays[i] = scan.nextInt();
}
if (N = N) return 1;
int res = 0,
min = Integer.MAX_VALUE;
int sum = 0;
for (int i = u; i < N; i++) {
if (arrays[i] < min) min = arrays[i];
sum += arrays[i];
int n = i - u + 1;
int q = min*n + n*(n-1)/2;
if (q == sum) {
res += dfs(i + 1);
res %= MOD;
}
}
return res;
}
}dfs 剪汁儿
import java.util.Arrays;
import java.util.Scanner;
public class Main__ {
static int N, MOD = (int)1e9+7;
static int[] arrays, cache;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
N = scan.nextInt();
arrays = new int[N];
cache = new int[N + 1];
for (int i = 0; i < N; i++) {
arrays[i] = scan.nextInt();
}
Arrays.fill(cache, -1);
System.out.println(dfs(0));
System.out.println(Arrays.toString(cache));
scan.close();
}
static int dfs(int u) {
if (u >= N) return 1;
int res = 0,
min = Integer.MAX_VALUE,
max = Integer.MIN_VALUE;
for (int i = u; i < N; i++) {
if (arrays[i] > max) max = arrays[i];
if (arrays[i] < min) min = arrays[i];
if (max - min == i - u) {
res += cache[i + 1] > -1 ? cache[i + 1] : dfs(i + 1);
res %= MOD;
}
}
cache[u] = res;
return res;
}
}从底向上循环
这个也是剪汁儿
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int[] arrays = new int[n];
for (int i = 0; i < n; i++) {
arrays[i] = scan.nextInt();
}
int MOD = (int) 1e9+7;
int[] cache = new int[n + 1];
cache[n] = 1;
for (int i = n - 1; i >= 0; i--) {
int min = Integer.MAX_VALUE;
int res = 0, sum = 0;
for (int j = i; j < n; j++) {
if (arrays[j] < min) min = arrays[j];
sum += arrays[j];
int l = j - i + 1;
int q = min*l + l*(l-1)/2;
if (q == sum) {
res += cache[j + 1];
res %= MOD;
}
}
cache[i] = res;
}
System.out.println(cache[0]);
scan.close();
}
}0.0分
3 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复