------------恢復內容開始------------c++
爲了方便(節約時間), 因此題面就不放到博客裏面了, 就直接鏈接放過去了spa
模擬賽傳送門.net
T1 - 樹的直徑
T2 - 積木
T3 - 軟件公司
T4 - 我圖呢code
因爲代碼和幫別人修題的緣故, 因此有一道題就沒改好, 因此就不放代碼了ip
T1 就是標準的 LCA。
能夠邊輸入處理父節點和深度, 再處理階乘就能夠了get
void dfs (int u, int fa) { p[u][0] = fa; for (reg int i = 1; (1 << i) <= hhd[u].deep; ++ i) p[u][i] = p[p[u][i - 1]][i - 1]; } int lca (int a, int b) { if (hhd[a].deep > hhd[a].deep) swap (a, b); for (reg int i = 20; i >= 0; -- i) if (hhd[a].deep <= hhd[b].deep - (1 << i)) b = p[b][i]; if(a == b) return a; for (reg int i = 20; i >= 0; -- i) { if (p[a][i] == p[b][i]) continue; else { a = p[a][i]; b = p[b][i]; } } return p[a][0]; } int main () { scanf ("%d", &m); for (reg int i = 1; i <= 4; ++ i) { hhd[i].deep = 1; hhd[i].y = 1; dfs (i, 1); } hhd[1].y = 0; hhd[1].deep = 0;
不是很難, 跳過博客
二分答案, 以一個三重循環的 DP 做爲 check 來二分。it
對於 \(f_{i,j}\) 表示前 \(i\) 我的 作了 \(j\) 項一個項目的子項目的狀況下能作的最多項二項目的子項目
而後咱們考慮從 \(f_{i-1, j-k}\) 來轉移狀態, 以使二項目完成的子項目最多, 同時使一項目完成的子項目符合 \(j\) 的大小io
#include <bits/stdc++.h> #define N 105 using namespace std; int n, m; int x[N], y[N], f[N][N]; int main () { freopen ("company.in", "r", stdin); freopen ("company.out", "w", stdout); scanf ("%d%d", &n, &m); for (int i = 1; i <= n; ++ i) scanf ("%d%d", &x[i], &y[i]); int l = 0, r = N - 5; while (l < r) { int mid = (l + r) / 2; memset (f, -0x3f3f3f, sizeof (f)); f[0][0] = 0; for (int i = 1; i <= n; ++ i) for (int j = 0; j <= m; ++ j) for (int k = 0; k <= j; ++ k) if (mid - k * x[i] < 0) break; else f[i][j] = max (f[i][j], f[i - 1][j - k] + (mid - k * x[i]) / y[i]); if (f[n][m] >= m) r = mid; else l = mid + 1; } printf ("%d", l); return 0; }
太過毒瘤, 沒改好, 不太好解析class