1. 程式人生 > >CodeForces 607B(DP初步_H題)解題報告

CodeForces 607B(DP初步_H題)解題報告

思路 algorithm 次數 spa cstring spl 移除 狀態轉移方程 color

題目鏈接:http://codeforces.com/problemset/problem/607/B

--------------------------------------------------------------------------------

題意:給出一個數字序列,若序列中存在子串存在回文串,可以進行消除,求出最小消除次數。

思路:區間dp,對於區間[i,j],如果a[i]==a[j],那麽f[i][j]==f[i+1][j-1],因為區間[i+1,j-1]一定能移除到與邊界2個構成回文串,但是要註意,如果區間長度等於2時,f[i][j]等於1並且有狀態轉移方程f[i][i+len-1]=min(f[i][i+len-1],f[i][k]+f[k+1][i+len-1]) (2<=len<=n,i<=k<i+len-1)

代碼:

技術分享圖片
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include
<map> #include<queue> using namespace std; typedef long long ll; const double PI = acos(-1.0); const double eps = 1e-6; const int MAXN = 500+10; int a[MAXN],f[MAXN][MAXN]; const int INF = 0x3f3f3f3f; int main(){ int n; while(~scanf("%d",&n)){ for(int i =0;i<n;i++) scanf("
%d",&a[i]); memset(f,INF,sizeof(f)); for(int i=0;i<n;i++) f[i][i]=1; for(int l=2;l<=n;l++){ for(int i=0;i+l-1<n;i++){ int j=i+l-1; if(a[i]==a[j]&&l>2) f[i][j]=f[i+1][j-1]; else if(a[i]==a[j]) f[i][j]=1; for(int k=i;k<j;k++){ f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]); } } } printf("%d\n",f[0][n-1]); } }
View Code

CodeForces 607B(DP初步_H題)解題報告