codeforces #336 D. Zuma (区间dp)

来源:互联网 发布:网络电视会员怎么开通 编辑:程序博客网 时间:2024/05/17 03:20

题目:http://codeforces.com/contest/608/problem/D

题意:给定长度为n(n<=500)的序列s,你每次可以消除一个连续回文子序列,问最少多少次可以把串消完。

分析:

定义dp[L][R]代表区间[L,R]的最少消除次数。

1.当L==R时:dp[L][R]=1;

2.当L<R时,

  --2.a) 当s[L]单独删掉,dp[L][R]=1+dp[L+1][R];

  --2.b) 当s[L]作为回文串的一部分删掉时,那么s[L]==s[i],dp[L][R]=dp[L+1][i-1]+dp[i+1][R]。

3.当L>R时,dp[L][R]=1。此时区间的两个端点越过中点。         

代码:

#include <bits/stdc++.h>using namespace std;typedef long long LL;typedef unsigned long long ULL;const LL INF = 1E9+9;const int MI = ~0u>>1;const int maxn = 555;int dp[maxn][maxn],n,a[maxn];int dfs(int L,int R){if(L>R)return 1;else if(L==R)return 1;else{if(dp[L][R]!=INF)return dp[L][R];else{dp[L][R]=1+dfs(L+1,R);for(int i=L+1;i<=R;i++){if(a[L]==a[i]){if(i!=R)dp[L][R]=min(dp[L][R],dfs(L+1,i-1)+dfs(i+1,R));elsedp[L][R]=min(dp[L][R],dfs(L+1,i-1));}}}}return dp[L][R];}int main(){scanf("%d",&n);for(int i=0;i<maxn;i++)for(int j=0;j<maxn;j++)dp[i][j]=INF;for(int i=1;i<=n;i++)scanf("%d",&a[i]);printf("%d\n",dfs(1,n));return 0;}

0 0
原创粉丝点击