2026寒假做题记录
不断更新中...
Codeforces Round 1069 (Div. 2)
A. Little Fairy's Painting
开桶,模拟过程即可,发现 \(c_i\) 不变便跳出模拟,一定不会超时。
B. XOR Array
利用异或前缀和,设 \(b_i=a_1 \xor a_2\^{}...\^{}a_i\),则 \(b_{l-1}=b_r\),其他的 \(b_i\) 互不相等。答案\(a_i=b_i\^{}b_{i-1}\)。
C. Needle in a Haystack
字符串处理。
D. Wishing Cards
有意思的一个DP。
一眼就是 DP 题, 设 \(d_{i,j,k}\) 为前 i 个点,总礼物价值 j,最大礼物为 k 时对答案的贡献。容易写出方程:
\(d_{i,j,k}=MAX\{d_{i-1,j,k}, MAX\{d_{i-1,j-k,y}+(k-y)\times(n-i+1)\}\}\)
拆开得:
\(d_{i,j,k}=MAX\{d_{i-1,j,k}, MAX_{y=0}^{k-1}\{d_{i-1,j-k,y}-y\times(n-i+1)\}+k(n-i+1)\}\)
这样写时间复杂度是 \(O(n\times k^3)\) 的。容易想到每次预处理 \(MAX_{y=0}^{k-1}\{d_{i-1,j-k,y}-y\times(n-i+1)\}\) 使时间复杂度降为 \(O(n\times k^2)\),但这依旧会超时。
注意到对于最佳答案的情况,对于所有选择放入礼物的点,他们的 \(a_i\) 一定是单调上升的,否则答案会更劣。这也就意味着我们只需要考虑单调上升的那些点,也就将 n 个点变为了 k 个点,时间复杂度 \(O(k^3)\) 。
#include <stdio.h>
#include <algorithm>
int n, m;
int a[100003];
int d[363][363], f[363][363];
inline void kagari () {
scanf("%d %d", &n, &m);
int bnt = 0, mxb = 0;
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
for (int i = 1; i <= n; ++i)
if (a[i] > mxb) mxb = a[i];
else a[i] = 0;
for (int i = 1; i <= m; ++i) for (int j = 1; j <= m; ++j) d[i][j] = f[i][j] = -n * m;
f[0][0] = 0;
for (int i = 1; i <= n; ++i) if (a[i]) {
for (int y = 1; y <= m; ++y)
for (int x = 1; x <= m; ++x)
f[x][y] = std:: max(d[x][y] - y * (n - i + 1), f[x][y - 1]);
for (int k = 1; k <= a[i]; ++k)
for (int j = k; j <= m; ++j)
d[j][k] = std:: max(d[j][k], k * (n - i + 1) + f[j - k][k]);
}
int ans = 0;
for (int j = 1; j <= m; ++j)
for (int k = 1; k <= m; ++k)
ans = std:: max(d[j][k], ans);
printf("%d\n", ans);
return;
}
int main () {
int t; scanf("%d", &t);
while (t--) kagari();
return 0;
}
( ゚∀゚)o彡゜ ヒーコー ヒーコー!

浙公网安备 33010602011771号