CodeForces

题目链接

题目大意

  从任意一个位置开始,将与这个位置上数字相同的数字改变成任意的数字,最后使所有数字都相同,问最少需要多少次。

解题思路

  数据量很明显可以用(n^2)做法,我们先让所有连续相同的数字都变成一个,方便转移。考虑区间dp,设dp[l][r]为区间[l,r]的最少代价,如果两端字符相同,那么它就能从子区间dp[l+1][r-1]转移过来,否则的话,有两种可能,可能是从[l+1,r]转移过来的,也可能是[l,r-1],取最优即可。由于我们之前把连续相同的数字都改成了一个,所以相邻的数字必不相同,每次的转移代价都需要+1。

代码

const int maxn = 5e3+10;
const int maxm = 2e5+10;
int dp[maxn][maxn], a[maxn], b[maxn], n, m;
int main() {
    cin >> n;
    for (int i = 1; i<=n; ++i) cin >> a[i];
    for (int i = 1; i<=n; ++i)
        if (a[i]!=a[i-1]) b[++m] = a[i];
    for (int len = 1; len<=m; ++len)
        for (int l = 1; l+len<=m; ++l) {
            int r = l+len;
            if (b[l]==b[r]) dp[l][r] = dp[l+1][r-1]+1;
            else dp[l][r] = min(dp[l+1][r], dp[l][r-1])+1;
        }
    cout << dp[1][m] << endl;
    return 0;
} 
原文地址:https://www.cnblogs.com/shuitiangong/p/14447239.html