[USACO07OPEN]便宜的回文Cheapest Palindrome
Posted clockwhite
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[USACO07OPEN]便宜的回文Cheapest Palindrome相关的知识,希望对你有一定的参考价值。
题目概要:对于用字典序中前n个小写字母组成的串,付出一定的代价来插入or删除使其成为回文串的最小代价。
解题思路:首先对于最优解,要么是贪心要么是DP。这题是DP。设f[i][i+l]为将a[i]~a[i+l]变成回文的最小代价。方程式:
①若a[i]==a[i+l] f[i][i+l]=f[i+1][i+l-1]
②s1=f[i][i+l-1]+增加代价;s2=f[i][i+l-1]+删减代价;s3=f[i+1][i+l]+增加代价;s4=f[i+1][i+l]+删减代价;f[i][i+l]=min(min(s1,s2),min(s3,s4));
如何理解这个方程式呢?对于当前的串,最好的情况无异于是首尾相同(满足回文的基础条件)且里面也回文(①的情况)。如果不满足就只有进行调整。情况一为,a[i+1][i+l]回文,删去a[i]或增加一个与a[i]相同的字母即可。情况二则以a[i+l]作为待调整的字母,与一同理(②的情况)。这样一来就可以出答案了。
又及:此方法适用于大多数有关于回文的DP
#include<iostream> #include<cstdio> #include<fstream> #include<cmath> #include<algorithm> #include<cstring> using namespace std; int read() char ch; int res=0,f=1; ch=getchar(); while(ch<‘0‘||ch>‘9‘) if(ch==‘-‘)f=-1; ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘) res=res*10+(ch-‘0‘); ch=getchar(); return res*f; int n,tot,ans,c[5005],s[5005],k; long long f[5005][5005]; char a[5005],ch; int main() k=read(); n=read(); for(int i=1;i<=n;++i) cin>>a[i]; for(int i=1;i<=k;++i) cin>>ch; c[ch-‘a‘]=read(); s[ch-‘a‘]=read(); for(int l=1;l<n;++l) for(int i=1;i+l<=n;++i) if(a[i]==a[i+l])f[i][i+l]=f[i+1][i+l-1]; else int s1=f[i][i+l-1]+c[a[i+l]-‘a‘], s2=f[i][i+l-1]+s[a[i+l]-‘a‘], s3=f[i+1][i+l]+c[a[i]-‘a‘], s4=f[i+1][i+l]+s[a[i]-‘a‘]; f[i][i+l]=min(min(s1,s2),min(s3,s4)); printf("%lld",f[1][n]); return 0;
以上是关于[USACO07OPEN]便宜的回文Cheapest Palindrome的主要内容,如果未能解决你的问题,请参考以下文章
[USACO07OPEN]便宜的回文Cheapest Palindrome
[luoguP2890] [USACO07OPEN]便宜的回文Cheapest Palindrome(DP)
bzoj1710Usaco2007 OpenCheappal 便宜回文
[BZOJ1710][Usaco2007 Open]Cheappal 廉价回文