体现了Educational。感觉对于萌新(我)或者回顾回顾还是不错的。
A - Frog 1
Description
给定 $n$ 个石头,石头高度分别为$h_1…h_n$。现在要求小青蛙从 $1$ 号石头跳到 $n$ 号石头,每次小青蛙可以选择从 $i$ 号石头跳到 $i+1$ 或 $i+2$ 号石头,代价是起跳点与落点的高度差的绝对值。求最小代价。
Solution
暴力dp。
令 $dp[i]$ 表示小青蛙跳到第 $i$ 号石头时的最小代价。
Complexity: $O(n)$
Code
1 | constexpr int maxn = 1e6+10; |
B - Frog 2
Description
给定 $n$ 个石头,第 $i$ 个石头的高度为 $h_i$ 。现要求小青蛙从 $1$ 号石头跳到 $n$ 号石头,每次小青蛙可以选择从 $i$ 号石头跳到 $i+t(1\le t\le k)$ 号石头,代价是起跳点与落点的高度差的绝对值。求最小代价。
Solution
暴力dp
设 $dp[i]$ 为小青蛙跳到第 $i$ 号石头时最小代价。
Complexity: $O(k*n)$
Code
1 | constexpr int maxn = 1e6+10; |
C - Vacation
Description
Taro有 $n$ 天假期,每天他可以进行三种活动中的一种,每种活动给他带来的愉悦值各不相同。如果当天进行过某一种活动,第二天即不能进行另一种活动,求 $n$ 天后Taro能获得的最大愉悦值。
Solution
令 $dp[i][j]$ 分别记录在第 $i$ 天选做第 $j$ 件娱乐活动的最大愉悦值。
Complexity: $O(n)$
Code
1 | int n , a[maxn], b[maxn], c[maxn], dp[maxn][3]; |
D - Knapsack 1
Description
01背包板子题
Solution
设 $dp[i]$ 为背包重量不超过 $i$ 时候最大价值。
Complexity: $O(N*W)$
Code
1 | int N , W, w[maxn],v[maxn],dp[105][100005]; |
E - Knapsack 2
Description
$n$ 件物品,大小和权值分别为 $w_i$,$v_i$,给定背包最大容量$W$ ,$MAX$ 化价值。
Solution
由于 $W$ 很大,所以不能如同 D 题的做法,但是发现价值很小,对价值进行背包。求出来达到某一个权值最小的重量,然后找到满足限制的最大的价值即可。(因为,如果能达到权值比这个还大的点,那么这个点很显然也是可以达到的。)
令 $dp[i]$ 表示装填价值为 $i$ 的物品的最小权值。
Complexity: $O(N*v)$
Code
1 | int v[maxn], w[maxn], dp[maxn], N , V; |
F - LCS
Description
输出字符串$s,t$的最长公共子串。
Solution
令 $dp[i][j]$ 表示 $s$ 的长度为 $i$ 的前缀和 $t$ 的长度为 $j$ 的前缀的最长公共子串。
自底向上输出这个串。
Complexity: $O(n^2)$
Code
1 |
|
G - Longest Path
Description
求 DAG 上的最长路径。
Solution
DAG上 dp。
Complexity: $O(n)$
Code
1 | const int N = 1e6+100; |
按照 $DFS$ 序,$f[i]$ 表示从 $i$ 号点出发的最长路径上点的数量。
Complexity: $O(n)$1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using namespace std;
int hd[N], nx[M], e[M];
int f[N], v[N], n, m;
int dfs(int x) {
if (f[x]) return f[x];
for (int i = hd[x]; i; i = nx[i]) f[x] = max(f[x], dfs(e[i]));
return ++f[x];
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1, Num = 0, x, y; i <= m; i++) {
scanf("%d%d", &x, &y);
nx[++Num] = hd[x], hd[x] = Num, e[Num] = y;
}
int ans = 0;
for (int i = 1; i <= n; i++) ans = max(ans, dfs(i));
printf("%d\n", ans - 1);
return 0;
}
H - Grid 1
Description
给定一个 $H,W$ 的网格,每次$(i,j)$可以到达$(i+1,j)$或者$(i),j+1$,有一些障碍。求从$(1,1)$到达$(H,W)$ 的方案数。
Solution
暴力dp
设$dp[i][j]$表示从$(1,1)$到达$(i,j)$的移动方案。
Complexity: $O(H\times W)$
Code
1 | // She is Pretty pretty! |
I - Coins
Description
给定 $n(is \ odd)$ 个硬币,扔第 $i$ 个硬币时,它正面朝上的概率为 $p_i$ 。
求每一个硬币扔一次,正面朝上的数量多余反面朝上的硬币的数量的概率。
Solution
概率DP,记有 $i$ 个正面朝上的概率
Complexity: $O(n^2)$
Code
1 | // She is Pretty pretty! |
J - Sushi
Description
有$n$个盘子,每盘里有 1到 3份食物。每次随机选中一份食物,若该盘中有食物,则吃掉一份。
求期望选择次数。
Solution
期望问题。
记忆化搜索。
设$dp[i][j][k]$为有 i 盘一份食物, j 盘二份食物, k 盘三份食物的期望选择次数。
Complexity: $O(n^3)$?? dont know
Code
1 | // She is Pretty pretty! |
K - Stones
Description
给定 $n,k$ ,和集合 $\mathbb{A}$,$a_i\in\mathbb{A}$,总共$k$个石子,每次在集合 $\mathbb{A}$ 可取石 $x$,无法取石子的为输。问赢家是谁。
Solution
博弈结论。
设 $dp[i]$ 为先手的胜负状态。 胜负 局面 转移一下就行了。
Code
1 | // She is Pretty pretty! |
L - Deque
Description
给定一个序列 $a$ ,alice和bob轮流进行博弈,太郎先行。
每次可以从序列的两端中任取一端,删去那一段的第一个元素,并获取等量的分数。
alice 和 bob 都希望能最大化自己与对面的得分差,询问你最终 alice 与 bob 的得分差。
Solution
设 $dp[i][j]$表示剩余区间为 $[i,j]$ 时候的最大得分差。
状态转移方程为:$dp[l][r] = max(a[l] - dp[l+1][r], a[r]-dp[l][r-1] );$
取减号是因为:上一个人的负值是下一个人的正值。
Complexity: $O(n^2)$
Code
1 | // She is Pretty pretty! |
M - Candies
Description
有 $n$ 个小朋友的需求,第 $i$ 个小朋友的需求为 $a_i$ ,表示他可以接受 $[0,a_i]$ 个糖果。
给定 $m$ 个糖果,把这些糖果全部分配出去,求有多少种分配方案。
Solution
设$dp[i][j]$为分配前 $i$ 个小朋友还剩 $j$ 个糖果的方案数。
Complexity: $O(n*k)$
Code
1 |
|