1 条题解
-
0
自动搬运
来自洛谷,原作者为

wh_ZH
自闭了喵搬运于
2025-08-24 22:14:52,当前版本为作者最后更新于2019-12-20 18:05:15,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
既然都写过了就在题解区再发一遍给定一个字符串和一个 的矩阵 ,表示可以消耗 的代价把字符 改成字符 ,求把原字符串改成每个连续段长度都不小于 的最小代价。
首先直接用原矩阵的交换方法不一定最优,拿到手先跑一遍 floyd。
然后考虑 dp , 表示前 个中每个连续段都 的最小代价,显然有转移
其中 表示把 全都改成字符 的最小代价,这个可以前缀和预处理。
观察转移,发现可以在枚举到 时再把 的决策加进去,这样维护一个前缀 即可做到 转移。
复杂度
#include <bits/stdc++.h> using namespace std; const int N=100005; int c[30][30],f[N]; char s[N]; int sum[30][N]; int query(int x,int l,int r){ return sum[x][r]-sum[x][l-1]; } int mn[30]; int main (){ freopen ("cowmbat.in","r",stdin); freopen ("cowmbat.out","w",stdout); int n,m,k;scanf ("%d%d%d",&n,&m,&k); scanf ("%s",s+1); for (int i=0;i<m;i++) for (int j=0;j<m;j++) scanf ("%d",&c[i][j]); for (int l=0;l<m;l++) for (int i=0;i<m;i++) for (int j=0;j<m;j++) if (i!=j&&j!=l&&i!=l) c[i][j]=min(c[i][j],c[i][l]+c[l][j]); for (int i=0;i<m;i++) for (int j=1;j<=n;j++) sum[i][j]=c[s[j]-'a'][i]+sum[i][j-1]; memset (mn,0x3f,sizeof(mn)); memset (f,0x3f,sizeof(f));f[0]=0; for (int i=k;i<=n;i++) for (int j=0;j<m;j++) mn[j]=min(mn[j]+c[s[i]-'a'][j],f[i-k]+query(j,i-k+1,i)),f[i]=min(f[i],mn[j]); printf ("%d",f[n]); return 0; }
- 1
信息
- ID
- 4844
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者