poj3280構成された最小コスト文字列回文 - 間隔DP

問題の意味

思考

DP [i]の[j]は、私は〜jと最適解が回文構造となっているこのセクションに保存されています

私たちは、新しいセクションを要求したときので、私は〜Jの必要性は、S [i]は?= S [j]を考えます

IF(S [I] == S [J])DP [I] [J] =分(DP [I]、[J]、DP [I +1] [J - 1])。

他DP [I] [J] =分(DP [I] [j]は、分(DP [I + 1] [J] +ちゃん[S [I]、DP [I]、[J - 1] +チャン[S [J]));

各文字列は、(ADDは、低減する)、これは分でチャンためときにS [i]には!= DPまでの時間S [j]は[I + 1] [j]はIであってもよく、1つのS [I]に変換するのいずれかの側廃棄ビットまたはS [j]を追加何かの後ろにS [i]は、コスト+ =分(ADDは、低減)DPは[J - 1] [i]と同じ手順であります

各DP [i] [j]は、このセクションで回文最適なソリューションを表していない後遺症などを直接後継者が回答バックには影響しませんです

ACcode

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>

using namespace std;
const int inf = 0x3f3f3f3f;

int n,len;
char op;
char s[2005];
int ad[30],re[30],chan[30];
int dp[2005][2005];

int main()
{
	scanf("%d %d",&n,&len);
	scanf("%s",s + 1);
	s[0] = '#',s[len + 1] = '#';
	for(int i = 1;i <= n; i++){
		scanf(" %c",&op);
		int cur = op - 'a';
		scanf("%d %d",&ad[cur],&re[cur]);
		chan[cur] = min(ad[cur],re[cur]);
	}
	memset(dp,0,sizeof dp);
	for(int i = 1;i <= len; i++){
		for(int j = i;j <= len; j++) dp[i][j] = inf;
	}
	for(int L = 1;L <= len; L++){
		for(int i = 1;i + L - 1 <= len; i++){
			int j = i + L - 1;
			if(s[i] == s[j]) dp[i][j] = min(dp[i][j],dp[i + 1][j - 1]);
			else dp[i][j] = min(dp[i][j],min(dp[i + 1][j] + chan[s[i] - 'a'],dp[i][j - 1] + chan[s[j] - 'a']));
		}
	}
	printf("%d\n",dp[1][len]);
}

 

公開された31元の記事 ウォンの賞賛5 ビュー1367

おすすめ

転載: blog.csdn.net/qq_43685900/article/details/102817275