01 交换串 题解
题意简述
给定一个长为
对于原题,是最大化得到的串中子序列
题目分析
首先,根据大名鼎鼎的「
我们进而发现,我们只会交换不同的字符,那么相同的字符之间的相对位置关系也是确定了的。这样,我们可以计算到达最终的字符串需要进行多少步,就是每一个
我们考虑 DP,记
记
其中
最终答案是
代码
#include <cstdio> #include <iostream> #include <cstring> using namespace std; const int N = 520; int n, m; char str[N]; int $0[N], $1; int f[2][N][N], ans; inline void tomax(int &a, int b) { b > a && (a = b); } signed main() { #ifndef XuYueming freopen("b6e6.in", "r", stdin); freopen("b6e6.out", "w", stdout); #endif scanf("%s%d", str + 1, &m); for (; str[n + 1]; ++n); for (int i = 1; i <= n; ++i) { if (str[i] == '0') $0[++*$0] = i; else ++$1; } memset(f[0], 0xff, sizeof (f[0])); f[0][0][0] = 0; for (int i = 0, t; i <= n - 1; ++i) { memset(f[(i + 1) & 1], 0xff, sizeof (f[(i + 1) & 1])); for (int j = max(0, i - $1); j <= i && j <= *$0; ++j) for (int k = 0; k <= m; ++k) if (~f[i & 1][j][k]) { tomax(f[(i + 1) & 1][j][k], f[i & 1][j][k] + (j * (j - 1) >> 1) * (*$0 - j)); if (j == *$0) continue; t = k + abs($0[j + 1] - i - 1); if (t <= m) tomax(f[(i + 1) & 1][j + 1][t], f[i & 1][j][k] + ((i - j) * (i - j - 1) >> 1) * ($1 - (i - j))); } } for (int i = m; i >= 0; i -= 2) ans = max(ans, f[n & 1][*$0][i]); printf("%d", ans); return 0; }
本文作者:XuYueming,转载请注明原文链接:https://www.cnblogs.com/XuYueming/p/18444469。
若未作特殊说明,本作品采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!