2025-10-15 ZROJ25普及联考day12 赛后总结
A.eat
原题链接:吃 | Zhengrui Online Judge
分析:dp(因为贪心不了),设dp[i][j]表示以第i张桌子结尾,第j种食物最长的出现次数。
转移:f[i][a[i]] = max(f[i - 1][a[i]] + 1, 1);
f[i][b[i]] = max(f[i - 1][b[i]] + 1, 1);
错误分析:打CF没打ZR。
OK,上正解:
#include <bits/stdc++.h>
using namespace std;
const int N = 100005, M = 10;
int n, a[N], b[N], f[N][M];
int main(){memset(f, 0xc0, sizeof(f)); //初始化cin >> n;for (int i = 1; i <= n; i++){cin >> a[i] >> b[i];f[i][a[i]] = max(f[i - 1][a[i]] + 1, 1);f[i][b[i]] = max(f[i - 1][b[i]] + 1, 1);}int ans = 0;for (int i = 1; i <= n; i++)for (int j = 1; j <= 5; j++)ans = max(ans, f[i][j]);cout << ans << " ";for (int i = 1; i <= n; i++)for (int j = 1; j <= 5; j++)if (f[i][j] == ans){cout << j;return 0;}
}
B.candy
原题链接:糖 | Zhengrui Online Judge
分析:我们发现,显然我们要把需求均摊(分剩下的),这样在、才能使得平方和最小(贪心)。那么我们二分(最开始分的)一下就行。
错误分析:打CF没打ZR。其实是糖了,只想着贪心了。
正解:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 100005;
int n, m, a[N];
bool check(int x){int now=0;for (int i = 1; i <= n; i++) if (a[i] > x) now += a[i] - x;return now <= m;
}
signed main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin >> m >> n;for (int i = 1; i <= n; i++) cin >> a[i];int l = 0, r = 1e18;while (l < r){ //二分给每个人分多少糖int mid = (l + r) >> 1;if (check(mid)) r = mid;else l = mid + 1;}int now = 0;for (int i = 1; i <= n; i++) if (a[i] > l){now += a[i] - l;a[i] = l;}now = m - now;sort(a + 1, a + 1 + n, greater<int>());for (int i = 1; i <= n && now; i++, now--) //均摊a[i]--;long long ans = 0;for (int i = 1; i <= n; i++) ans += a[i] * a[i];cout << ans; return 0;
}
lz原谅我,真得打CF了,T3,T4之后再补。