洛谷 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;
}

  

posted @ 2017-10-28 17:02  啊宸  阅读(304)  评论(0编辑  收藏  举报