【CF-607B】Zuma 经典区间DP

B.Zuma

题意

给出一个长度为n的整数数组,每次可以去掉一个连续的回文子序列。

剩下的会靠拢,问最少几次可以去完。

题解

经典区间DP。

\(dp[i][j]\)表示把区间\([i,j]\)消除完的最小值

转移方程:

if arr[i]==arr[j]: dp[i][j]=dp[i+1][j-1]

dp[i][j]=min(dp[i][k],dp[k+1][j])

代码

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<math.h>
#define pb push_back
typedef long long ll;
using namespace std;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const int N = 500+10;

int n,arr[N],dp[N][N];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&arr[i]);
    memset(dp,inf,sizeof(dp));
    for(int i=1;i<=n;i++) dp[i][i]=1;
    for(int i=2;i<=n;i++)
    {
        for(int j=1;i+j-1<=n;j++)
        {
            int en=i+j-1;
            if(arr[j]==arr[en])
            {
                if(j+1==en) dp[j][en]=1;
                else dp[j][en]=dp[j+1][en-1];
            }
            for(int k=j;k<en;k++) 
                dp[j][en]=min(dp[j][en],dp[j][k]+dp[k+1][en]);
        }
    }
    printf("%d\n",dp[1][n]);
    return 0;
}
/*
*/
posted @ 2020-05-21 11:00  Valk3  阅读(109)  评论(0编辑  收藏  举报