CodeForces 1114DFlood Fill(区间DP)

题目链接:https://codeforces.com/problemset/problem/1114/D

题目大意:给出n个数字,从任意一个数字开始,将其变成左右相同的数字,最后所有数字相同,问最少变多少次

Examples

Input
4
5 2 2 1
Output
2
Input
8
4 5 2 2 1 3 5 5
Output
4
Input
1
4
Output
0

emmmm,区间DP,设置状态为dp[i][j],没什么好说的,比较普通,因为是相同的连续数字可以看出一块,所以我们首先可以直接将所有相同的连续数字合并,那么这样一来,每个数字的左邻右舍都是不同的数字了。接下来就是状态转移,对于区间$[l,r]$来讲,它是由区间$[l+1,r]$或者$[l,r-1]$转移过来的,那么转移的时候我们看看两边的数字是否一样,如果一样的话那么就没什么好说的了,直接:$dp[l][r]=dp[l+1][r-1]+1;$,否则的话我们就需要对两种转移状态取个最小值就OK了

以下是AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int mac=5e3+10;

int color[mac],dp[mac][mac];

int main(int argc, char const *argv[])
{
    int n,pre=-1,cnt=0;
    scanf ("%d",&n);
    for (int i=1; i<=n; i++){
        int x;
        scanf ("%d",&x);
        if (x!=pre) color[++cnt]=x;
        pre=x;
    }
    for (int len=2; len<=cnt; len++){
        for (int l=1; l+len-1<=cnt; l++){
            int r=l+len-1;
            if (color[l]==color[r]) dp[l][r]=dp[l+1][r-1]+1;
            else dp[l][r]=min(dp[l+1][r],dp[l][r-1])+1; 
        }
    }
    printf("%d\n",dp[1][cnt]);
    return 0;
}
posted @ 2020-07-07 23:18  lonely_wind  阅读(230)  评论(0编辑  收藏  举报