前言
这是第二场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, 0
mod = 10 ** 9 + 7
for i in range(n):
s0, s1, s2, s3 = s0 + s1 + s2 + s3, s0 + s2, s0 + s1, s0
s0 %= mod
s1 %= mod
s2 %= mod
s3 %= mod
print ((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 0
if tag == 0 and f == 0:
return 0
dp = [-inf] * 3
dp[f] = arr[0][f]
for i in range(1, n):
v1, v2, v3 = arr[i]
dp2 = [-inf] * 3
if i % 2 == tag:
dp2[1] = dp[0] + v2
dp2[2] = max(dp[0], dp[1]) + v3
else:
dp2[0] = max(dp[1], dp[2]) + v1
dp2[1] = dp[2] + v2
dp = dp2
res = 0
for 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 res
ans = 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 heapq
hq = []
res = 0
tmp = 0
acc = 0
for i in range(n):
if i > 0:
acc += es[i - 1]
if acc > T:
break
while acc + len(hq) > T and len(hq) > 0:
tmp -= heapq.heappop(hq)
j = 0
while True:
ng = us[i] - j * vs[i]
if ng <= 0:
break
if acc + len(hq) < T:
heapq.heappush(hq, ng)
tmp += ng
else:
if len(hq) > 0 and hq[0] >= ng:
break
tmp -= heapq.heappop(hq)
heapq.heappush(hq, ng)
tmp += ng
j += 1
res = 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)