A. Flipping Game
A. Flipping Game
本质上是让我们找出一段区间内\(0\)的个数大于\(1\)的个数的最多的区间,且必须进行一次操作,所以可以考虑区间\(dp\),或者最小子序列和
1 最小子序列和
\[\begin{aligned}
dp_i是以a_i结尾的最小子序列和 \\
dp_i=\min(dp_{i-1}+a[i],a[i])
\end{aligned}
\]
#include <bits/stdc++.h> #define debug(a) cout<<#a<<"="<<a<<'\n'; using namespace std; using i64 = long long; typedef pair<i64, i64> PII; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; vector<int> a(n + 1); i64 ans = 0 ; for (int i = 1; i <= n; i ++) { cin >> a[i]; ans += a[i]; if (!a[i]) a[i] = -1; } if (ans == n) ans --; vector<int> dp(n + 1); int k = 0; for (int i = 1; i <= n; i ++) { dp[i] = min(dp[i - 1] + a[i], a[i]); if (dp[i] < dp[k]) k = i; } cout << ans - dp[k] << '\n'; return 0; }
2 区间dp
\[\begin{aligned}
dp_{i,j}&为从i到j区间所有元素取反的和 \\
dp_{i,j}&=\max(dp_{i+1,j}+(1-a_i),dp_{i,j-1}+(1-a_j))
\end{aligned}
\]
#include <bits/stdc++.h> #define debug(a) cout<<#a<<"="<<a<<'\n'; using namespace std; using i64 = long long; typedef pair<i64, i64> PII; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; vector<int> a(n + 1), pre(n + 1); vector dp(n + 2, vector<int>(n + 2)); int ans = 0 ; for (int i = 1; i <= n; i ++) { cin >> a[i]; pre[i] = pre[i - 1] + a[i]; dp[i][i] = a[i] ^ 1; } for (int len = 1; len <= n; len ++) {//枚举区间长度 for (int i = 1; i + len - 1 <= n; i ++) { int j = i + len - 1; dp[i][j] = max(dp[i + 1][j] + (a[i] ^ 1), dp[i][j - 1] + (a[j] ^ 1)); ans = max(ans, pre[i - 1] + dp[i][j] + pre[n] - pre[j]); } } cout << ans << '\n'; return 0; }
本文作者:Ke_scholar
本文链接:https://www.cnblogs.com/Kescholar/p/17871740.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步