题意以及判断
连续子数组,这是重点哈,连续子数组我总结了以下几个性质:
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、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复