codeforces 607B- Zuma(区间DP)

传送门:QAQQAQ

 

题意:给你一个数组,每次可以删一个连续的回文串(包括长度为1),问最少删几次

 

思路:挺简单的DP题,但要想清楚有难度(先看数据范围,n^3可以过)

区间DP,dp[i][j]可以有两种情况更新而来:

1.a[i]==a[j],把最外面一层挖掉,答案为dp[i+1][j-1]

2.对于所有dp[i][j],枚举中间点,把它切成两半,分别求回文串加起来

为减少更新时溢出等不必要的麻烦,我把len=1或2都特判掉了

 

代码:

#include<bits/stdc++.h>
using namespace std;
const int inf=(int)2e9;
 
int dp[505][505];
int n,a[505];
 
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
    {
        for(int j=i;j<=n;j++)
        {
            if(i==j) dp[i][j]=1;
            else dp[i][j]=inf;
        }
    }
    for(int i=1;i<n;i++)
    {
        if(a[i]==a[i+1]) dp[i][i+1]=1;
        else dp[i][i+1]=2;
    }
    for(int len=3;len<=n;len++)
    {
        for(int i=1;i<=n-len+1;i++)
        {
            int j=i+len-1;
            if(a[i]==a[j]) dp[i][j]=dp[i+1][j-1];
            for(int k=i;k<j;k++)
            {
                dp[i][j]=min(dp[i][k]+dp[k+1][j],dp[i][j]);
            }
        }
    }
    cout<<dp[1][n]<<endl;
}
View Code

 

posted @ 2019-07-11 23:08  'Clovers'  阅读(135)  评论(0编辑  收藏  举报