ABC225F String Cards
题意
给你
分析
由于顺序不固定,所以我们无法直接 DP。而状压的复杂度也太高了,怎么办呢?
考虑钦定一个顺序,使得按照这个顺序排列字符串一定最优。
一个经典的错误想法是:将字符串按照字典序升序排序。
hack:ba b
,最优排列是 bab
,但由于 b
<ba
,所以我们的程序会得出 bba
的结果。
考虑 exchange argument 贪心,设字符串
考虑把这两个字符串写成哈希的形式,即
关于 DP,我们仍然有一个经典错误想法:设 ba
和 b
两个串,它们之后都要接 qwqwq
这个串,不难发现 baqwqwq
是字典序最小的,但由于 b
字典序比 ba
小,所以 DP 出来的方案是 bqwqwq
,本质上是因为当字符串长度不相同时,我们只考虑一开始的字典序大小关系,而没有考虑拼上字符串后的字典序大小关系。也就是说,若要从前往后取,为了保证字典序比较正确,我们还需要记录一维状态表示取的字符串长度,这样复杂度五方,就又上天了。
这种正着 DP 要记录很多额外状态的题,有一种经典方案是考虑倒着 DP。设
代码非常好写:
const int maxn=55;
int n,k;
string s[maxn],f[maxn][maxn];
bool cmp(string x,string y){return x+y<y+x;}
void solve_the_problem(){
cin>>n>>k;
rep(i,1,n)cin>>s[i];
sort(s+1,s+n+1,cmp);
rep(i,1,n)f[i][1]=s[i];
per(i,n-1,1)rep(j,2,n)rep(k,i+1,n)if(f[k][j-1]!=""){
string res=s[i]+f[k][j-1];
if(f[i][j]=="")f[i][j]=res;
else f[i][j]=min(f[i][j],res);
}
string ans=f[1][k];
rep(i,2,n)if(f[i][k]!="")ans=min(ans,f[i][k]);
cout<<ans;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探