前言
这是第二场CCF的练习赛,找找手感,顺便熟悉下赛氪OJ平台。
当前就做了5题,感觉还可以,部分题目质量蛮高的,但是易错。
第1题dp入门题, 第5属于诈骗题,第2和第3挺有难度的,第四题感觉放水了。
真题
Hotpot
思路: 状态机DP
这是时间复杂度为 o ( n ) o(n) o(n)
应该是存在矩阵幂的解法的
n = int(input())s0, s1, s2, s3 = 1, 0, 0, 0mod = 10 ** 9 + 7
for i in range(n):s0, s1, s2, s3 = s0 + s1 + s2 + s3, s0 + s2, s0 + s1, s0s0 %= mods1 %= mods2 %= mods3 %= modprint ((s0+s1+s2+s3)%mod)
Hearthstone
思路:环型DP
其实也是线性DP,无非多了一个环型限制,题目保证n为偶数。
# 思维题n = int(input())arr = []
for _ in range(n):v1, v2, v3 = list(map(int, input().split()))arr.append((v1, v2, v3))from math import inf
def solve(f, tag):if tag == 1 and f == 2:return 0if tag == 0 and f == 0:return 0dp = [-inf] * 3dp[f] = arr[0][f]for i in range(1, n):v1, v2, v3 = arr[i]dp2 = [-inf] * 3if i % 2 == tag:dp2[1] = dp[0] + v2dp2[2] = max(dp[0], dp[1]) + v3else:dp2[0] = max(dp[1], dp[2]) + v1dp2[1] = dp[2] + v2dp = dp2res = 0for i in range(3):if tag == 0 and f > i:res = max(res, dp[i])elif tag == 1 and f < i:res = max(res, dp[i])return resans = 0
for i in range(0, 3):for j in (0, 1):ans = max(ans, solve(i, j))print (ans)
Best Travel Plans
思路: 反悔堆
挺难的这题,一开始普通的BFS写法,TLE到奔溃
然后想了想,是不是可以枚举最远的位子,然后贪心求解。
这样的话,就可以构建反悔堆求解最优场景了。
n, T = list(map(int, input().split()))es = list(map(int, input().split()))
us = list(map(int, input().split()))
vs = list(map(int, input().split()))from math import inf
import heapqhq = []res = 0
tmp = 0
acc = 0
for i in range(n):if i > 0:acc += es[i - 1]if acc > T:breakwhile acc + len(hq) > T and len(hq) > 0:tmp -= heapq.heappop(hq)j = 0while True:ng = us[i] - j * vs[i]if ng <= 0:breakif acc + len(hq) < T:heapq.heappush(hq, ng)tmp += ngelse:if len(hq) > 0 and hq[0] >= ng:breaktmp -= heapq.heappop(hq)heapq.heappush(hq, ng)tmp += ngj += 1res = max(res, tmp)print (res)
Tree
解题突破口: n ≤ 1000 n \le 1000 n≤1000
这题就是单纯的模拟,就算二叉搜索树退化为链表,最多 O ( n 2 ) O(n^2) O(n2)
涉及DFS操作,采用java编写
import java.io.BufferedInputStream;
import java.util.Scanner;public class Main {static class TreeNode {int val;TreeNode left, right;public TreeNode(int val) {this.val = val;}public void insert(int v) {if (this.val == v) return;if (this.val > v) {if (this.left == null) {this.left = new TreeNode(v);return;}this.left.insert(v);} else if (this.val < v) {if (this.right == null) {this.right = new TreeNode(v);return;}this.right.insert(v);}}public int insert(int v, int depth) {if (this.val == v) return depth;else if (this.val > v) {if (this.left == null) {return depth + 1;}return this.left.insert(v, depth + 1);} else {if (this.right == null) {return depth + 1;}return this.right.insert(v, depth +1);}}}public static void main(String[] args) {Scanner sc = new Scanner(new BufferedInputStream(System.in));int n = sc.nextInt();TreeNode root = null;int v = sc.nextInt();root = new TreeNode(v);for (int i = 1; i < n; i++) {int t = sc.nextInt();root.insert(t);}for (int i = 0; i < n; i++) {int t = sc.nextInt();System.out.println(root.insert(t, 1));}}}
Flower
思路: 排序即可
题目感觉有些绕,挺无语的,小诈骗吧
n, k = list(map(int, input().split()))arr = list(map(int, input().split()))
brr = list(map(int, input().split()))ls = brr
ls.sort(key=lambda x: -x)res = 0
for i in range(min(k, len(ls))):res += ls[i]
print (res)