POJ3280 Cheapest Palindrome 区间DP
好久不做DP了。。。
题意:求原串通过删除和添加某些字符构成回文串的最小代价
设f[i][j]表示i到j位匹配的最小代价,那么有
f[i][j]=Inf; if(ch[i]==ch[j]) f[i][j]=f[i+1][j-1]; f[i][j]=min(f[i][j],f[i][j-1]+min(vl[ch[j]][1],vl[ch[j]][0])); f[i][j]=min(f[i][j],f[i+1][j]+min(vl[ch[i]][1],vl[ch[i]][0]));
其中vl[char][0/1]表示添加或删除char 的代价
#include<cstdio> #include<iostream> #define R register int const int Inf=0x3f3f3f3f; using namespace std; inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } int n,m,f[2010][2010]; int vl[128][2]; char ch[2010]; signed main() { n=g(),m=g(); for(R i=1;i<=m;++i) ch[i]=getchar(); for(R i=1;i<=n;++i) { register char ch; while(!isalpha(ch=getchar())); vl[(int)ch][0]=g(),vl[(int)ch][1]=g(); } //for(R i='a';i<='z';++i) cout<<vl[i][0]<<" "<<vl[i][1]<<endl; for(R l=2;l<=m;++l) for(R i=1,j=l;j<=m;++i,++j) { f[i][j]=Inf; if(ch[i]==ch[j]) f[i][j]=f[i+1][j-1]; f[i][j]=min(f[i][j],f[i][j-1]+min(vl[ch[j]][1],vl[ch[j]][0])); f[i][j]=min(f[i][j],f[i+1][j]+min(vl[ch[i]][1],vl[ch[]][0])); } printf("%d\n",f[1][m]); }
2019.04.06