BZOJ4607 : [PA2015 Final]Edycja
显然做完操作后再做操作。
建立一个个点的有向图,每个点只有一条出边,->表示最终变成了,边权为一开始是,最后不是的位置个数,如果,则代价还要增加。
对于每个点贪心选取最小的出边,如果没有环,那么此时就是最优解。
否则,对于一个连通块,如果它是环,那么需要多付出点代价,而且如果所有连通块都是环或者孤立点,则不可能构造出这种图。
考虑重新决定每个点的出边,如果出现了原来贪心构造出的图中不存在的环,那么一定有一个点的出边和一开始不同,因为一开始是贪心选最小,因此把那条边改回最开始的出边,答案不会增加,而且新环被破坏了。因此对于不是原来中的图的环,一定存在一种方案与它代价相同,且不存在这个环。
于是设表示考虑了前个字符,集合的环已经被破坏,是否和原图一样为时边权的最小值,DP即可。
因为最多只有个环,所以时间复杂度为。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #include<cstdio> const int N=26,M=1000010,inf=~0U>>1; int n,c,m,flag,i,j,k,S,U,v[N][N],ap[N],w[N][N],g[N],fa[N],d[N],vis[N],del[N],id[N]; int f[N+1][1<<(N/2)][2],ans; char a[M],b[M]; int F( int x){ return fa[x]==x?x:fa[x]=F(fa[x]);} inline void up( int &a, int b){ if (a>b)a=b;} int main(){ scanf ( "%d%d%s%s" ,&n,&c,a,b); for (i=0;i<n;i++)v[a[i]- 'a' ][b[i]- 'a' ]++,ap[a[i]- 'a' ]++; for (i=0;i<N;i++) for (j=0;j<N;j++){ w[i][j]=ap[i]-v[i][j]; if (i!=j)w[i][j]+=c; } for (i=0;i<N;i++)fa[i]=i,id[i]=-1; for (i=0;i<N;i++){ for (k=j=0;j<N;j++) if (w[i][j]<w[i][k])k=j; d[g[i]=k]++; if (F(i)!=F(k))fa[fa[i]]=fa[k]; } for (i=0;i<N;i++) if (!del[F(i)]){ del[fa[i]]=vis[i]=1; for (j=g[i];!vis[j];j=g[j])vis[j]=1; if (g[j]==j) continue ; for (id[j]=m,k=g[j];k!=j;k=g[k])id[k]=m; m++; } if (!m){ for (i=0;i<N;i++)ans+=w[i][g[i]]; return printf ( "%d" ,ans),0; } for (flag=1,i=0;i<N;i++) if (d[i]!=1)flag=0; for (i=0;i<=N;i++) for (S=0;S<1<<m;S++) for (j=0;j<2;j++)f[i][S][j]=inf; f[0][0][0]=0; for (i=0;i<N;i++) for (S=0;S<1<<m;S++) for (j=0;j<2;j++) if (f[i][S][j]<inf) for (k=0;k<N;k++){ U=S; if (~id[i]&&k!=g[i])U|=1<<id[i]; if (~id[k]&&(k!=g[i]||id[i]!=id[k]))U|=1<<id[k]; up(f[i+1][U][j||k!=g[i]],f[i][S][j]+w[i][k]); } for (ans=inf,S=0;S<1<<m;S++) for (j=flag;j<2;j++) if (f[N][S][j]<inf)up(ans,f[N][S][j]+(m-__builtin_popcount(S))*c); return printf ( "%d" ,ans),0; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决