abc 343
G Compress Strings
思路
-
一眼状压(n 只有 20)
-
分类讨论
- 如果
包含了 , 就没有 什么事了 - 否则考虑
加到 后面和反过来的代价- 就是求
的 border
- 就是求
- 如果
-
上述两个过程都可以 KMP 解决
代码
#include <bits/stdc++.h> #define int long long using namespace std; const int M = 1.5e6 + 10; const int N = 25; int n; int nxt[M], dp[M][N]; int cost[N][N], si; string s[N]; set <int> str; int Kmp(string s){ for(int i = 0; i < s.size(); i++){ nxt[i] = 0; } int j = 0; for(int i = 1; i < s.size(); i++){ while(j && s[i] != s[j]){ j = nxt[j - 1]; } if(s[i] == s[j]){ j++; } nxt[i] = j; if(nxt[i] == si){ return si; } } return nxt[s.size() - 1]; } signed main(){ // freopen("1.in", "r", stdin); cin >> n; for(int i = 1; i <= n; i++){ cin >> s[i]; str.insert(i); } for(int i = 1; i <= n; i++){ for(int j = 1; j <= n; j++){ if(s[i].size() > s[j].size() || i == j || str.find(j) == str.end()){ continue; } si = s[i].size(); if(s[i].size() == Kmp(s[i]+'#'+s[j])){ // cout << i << "i "; str.erase(i); } } } memset(dp, 0x3f3f3f3f, sizeof(dp)); int cnt = 0; si = -1; for(auto i : str){ for(auto j : str){ int ret = s[j].size() - Kmp(s[j]+"#"+s[i]); cost[i][j] = ret; } dp[1<<cnt][cnt] = s[i].size(); cnt++; } int up = (1 << str.size()) - 1; for(int i = 0; i <= up; i++){ int cnt = 0; for(auto j : str){ if(!((i >> cnt) & 1)){ ++cnt; continue; } int cntt = 0; for(auto k : str){ if((i >> cntt) & 1){ cntt++; continue; } dp[i|(1<<cntt)][cntt] = min(dp[i|(1<<cntt)][cntt], dp[i][cnt] + cost[j][k]); cntt++; } ++cnt; } } int mini = (int)1e18; for(int i = 0; i < str.size(); i++){ // cout << dp[up][i] << " "; mini = min(mini, dp[up][i]); } cout << mini << "\n"; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话