洛谷 2890 [USACO07OPEN]便宜的回文Cheapest Palindrome
一道最简单的区间dp,然而我还是抄了题解。
//Twenty #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<vector> #include<cmath> #include<queue> #include<ctime> const int maxn=2005; typedef long long LL; using namespace std; int n,m,cost[30],a,b; char s[maxn]; namespace fastIO { const int sz=1<<15|1; char ch,buf[sz],*l,*r; void gechar(char &c) { if(l==r) r=(l=buf)+fread(buf,1,sz,stdin); c = l==r?(char)EOF:*l++; } template<typename T> void read(T &x) { int f=1; x=0; gechar(ch); while(ch!='-'&&(ch<'0'||ch>'9')) gechar(ch); if(ch=='-') f=-1,gechar(ch); for(;ch>='0'&&ch<='9';gechar(ch)) x=x*10+ch-'0'; x*=f; } } int dp[maxn][maxn]; void work() { memset(dp,127,sizeof(dp)); for(int i=1;i<=m;i++) { dp[i][i]=0; if(s[i]==s[i+1]) dp[i][i+1]=0; } for(int l=2;l<=m;l++) { for(int i=1;i+l-1<=m;i++) { int j=i+l-1; if(l>2&&s[i]==s[j]) dp[i][j]=min(dp[i][j],dp[i+1][j-1]); dp[i][j]=min(dp[i][j],dp[i][j-1]+cost[s[j]-'a']); dp[i][j]=min(dp[i][j],dp[i+1][j]+cost[s[i]-'a']); } } printf("%d\n",dp[1][m]); } void init() { fastIO::read(n); fastIO::read(m); char ch; fastIO::gechar(ch); while(ch<'a'||ch>'z') fastIO::gechar(ch); for(int i=1;i<=m;i++) { s[i]=ch; fastIO::gechar(ch); } for(int i=1;i<=n;i++) { fastIO::gechar(ch); while(ch<'a'||ch>'z') fastIO::gechar(ch); fastIO::read(a); fastIO::read(b); cost[ch-'a']=min(a,b); } } //#define DEBUG int main() { #ifdef DEBUG freopen("1.in","r",stdin); //freopen(".out","w",stdout); #endif init(); work(); return 0; }