您的位置:首页 > 移动开发

【BZOJ】1710: [Usaco2007 Open]Cheappal 廉价回文

2017-09-26 10:15 417 查看

【算法】区间DP

【题解】回文问题的套路做法:区间DP。

f[i][j]表示区间i~j回文的最小代价,则有f[i][j]=min{①②③}。

①f[i+1][j]+min(a[s[i]],b[s[i]])

②f[i][j-1]+min(a[s[j]],b[s[j]])

③f[i+1][j-1],s[i]==s[j]

注意初始化,f[i][i]=f[i][i+1]=f[i+1][i]=0,偶数回文时初始状态会交错。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=2010;

int n,m,s[maxn],a[30],f[maxn][maxn];
char ss[maxn];
int main(){
scanf("%d%d%s",&n,&m,ss+1);
for(int i=1;i<=m;i++)s[i]=ss[i]-'a';
int b,c;
for(int i=1;i<=n;i++){
scanf("%s",ss+1);
scanf("%d%d",&b,&c);
a[ss[1]-'a']=min(b,c);
}
memset(f,0x3f,sizeof(f));
for(int i=1;i<=m;i++)f[i][i]=0,f[i][i+1]=f[i+1][i]=0;//
for(int p=2;p<=m;p++){
for(int i=1;i<=m-p+1;i++){
int j=i+p-1;
f[i][j]=min(f[i+1][j]+a[s[i]],f[i][j-1]+a[s[j]]);
if(s[i]==s[j])f[i][j]=min(f[i][j],f[i+1][j-1]);
}
}
printf("%d",f[1][m]);
return 0;
}
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: