题面

传送门

分析

法1(区间DP):

首先,我们可以把连续的相等区间缩成一个数,用unique来实现,不影响结果

{1,2,2,3,3,3,5,3,4}->{1,2,3,5,3,4}

先从一个极端情况来考虑,a={1,2,3,4,5},此时答案显然为4,从1个点出发,先把它变成和左边的点相等,再把它变成和右边的点相等,一共需n-1次

假设我们已经把中间某个区间[i,j]变成相同颜色的一段,如{1,5,5,5,5,4}

如果a[i-1]!=a[j+1],则需要变两次,如果a[i-1]=a[j+1],只需要变一次了,

所以我们需要求出形如a[i-1]=a[j+1]的数对个数ans,由于每个这样的数对会少变一次

所以答案就是n-1-ans

那么如何求出ans呢

区间DP,\(dp[i][j]\)表示区间\([i,j]\)外的数对个数

则\(dp[i][j]=\begin{cases} max(dp[i-1][j],dp[i][j+1]) \\ max(dp[i-1][j],dp[i][j+1],dp[i-1][j+1]+1),a[i-1]=a[j+1]\end{cases}\)

初始值\(dp[1][n]\)=0

最后得到的\(dp[i][i]\)表示除了i之外的数列中的数对个数,即从i开始变需要变n-1-\(dp[i][i]\)次

取\(dp[i][i]\)的最大值即可

时间复杂度\(O(n^2)\)


法二(CF官方题解的做法):

由法一的分析,我们注意到数对会形成回文子序列

如{1,3,2,5,3,1},则1 3 2 3 1就形成了回文子序列,

显然变化次数为n-(回文子序列长度+1)/2

因此我们只要求出最长的回文子序列长度,可以把原串和反串跑LCS,时间复杂度\(O(n^2)\)

用LCS转LIS可以优化到\(O(n\log n)\)

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#define maxn 5005
using namespace std;
int n;
int a[maxn];
int dp[maxn][maxn];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
n=unique(a+1,a+1+n)-a-1;
dp[1][n]=0;
for(int len=n-1;len>=1;len--){
for(int i=1;i+len-1<=n;i++){
int j=i+len-1;
dp[i][j]=max(dp[i-1][j],dp[i][j+1]);
if(i-1>=0&&j+1<=n&&a[i-1]==a[j+1]) dp[i][j]=max(dp[i][j],dp[i-1][j+1]+1);
}
}
int ans=0;
for(int i=1;i<=n;i++) ans=max(ans,dp[i][i]);
printf("%d\n",n-1-ans);
}

Codeforces 1114D(区间DP)的更多相关文章

  1. CodeForces 512B(区间dp)

    D - Fox And Jumping Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64 ...

  2. codeforces 1140D(区间dp/思维题)

    D. Minimum Triangulation time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  3. Timetable CodeForces - 946D (区间dp)

    大意: n天, 每天m小时, 给定课程表, 每天的上课时间为第一个1到最后一个1, 一共可以逃k次课, 求最少上课时间. 每天显然是独立的, 对每天区间dp出逃$x$次课的最大减少时间, 再对$n$天 ...

  4. CodeForces - 1107E 区间DP

    和紫书上的Blocks UVA - 10559几乎是同一道题,只不过是得分计算不同 不过看了半天紫书上的题才会的,当时理解不够深刻啊 不过这是一道很好区间DP题 细节看代码 #include<c ...

  5. CodeForces 149D 区间DP Coloring Brackets

    染色有三个条件: 对于每个点来说要么不染色,要么染红色,要么染蓝色 对于每对配对的括号来说,有且只有一个一边的括号被染色 相邻的括号不能染成相同的颜色 首先可以根据给出的括号序列计算出括号的配对情况, ...

  6. Zuma CodeForces - 607B (区间DP)

    大意: 给定字符串, 每次删除一个回文子串, 求最少多少次删完. #include <iostream> #include <cstdio> #define REP(i,a,n ...

  7. Recovering BST CodeForces - 1025D (区间dp, gcd)

    大意: 给定$n$个数, 任意两个$gcd>1$的数间可以连边, 求是否能构造一棵BST. 数据范围比较大, 刚开始写的$O(n^3\omega(1e9))$竟然T了..优化到$O(n^3)$才 ...

  8. Codeforces 940 区间DP单调队列优化

    A #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #def ...

  9. Codeforces 1114D Flood Fill (区间DP or 最长公共子序列)

    题意:给你n个颜色块,颜色相同并且相邻的颜色块是互相连通的(连通块).你可以改变其中的某个颜色块的颜色,不过每次改变会把它所在的连通块的颜色也改变,问最少需要多少次操作,使得n个颜色块的颜色相同. 例 ...

随机推荐

  1. 自己实现一个类似 jQuery 的函数库

    假如我们有一个需求,需要给元素添加样式类,使用原生的JS很容易搞定. 1 抽取函数 function addClass(node, className){ node.classList.add(cla ...

  2. Tesseract-OCR识别中文与训练字库

    转自:https://www.cnblogs.com/lcawen/articles/7040005.html 关于中文的识别,效果比较好而且开源的应该就是Tesseract-OCR了,所以自己亲身试 ...

  3. CS184.1X 计算机图形学导论(第三讲)

    第一单元(介绍关于变换的数学知识) :基本二维变换 模型坐标系,世界坐标系 1.缩放 Scale(规模,比例) Sx表示在x方向上放大的倍数,Sy表示在y方向上放大的倍数,因此X坐标乘以Sx,Y坐标乘 ...

  4. Vue 侦听属性

    Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性 <!DOCTYPE html> <html> <head> <meta cha ...

  5. java 字符串的截取、转换、分割

    1.截取 package java07; /* 字符串的截取方法: public String substring(int index):截取从参数位置一直到字符串末尾,返回新字符串 public S ...

  6. USACO2008 Jan 电话网络

    Time Limit: 10 Sec Memory Limit: 162 MB Description Farmer John决定为他的所有奶牛都配备手机,以此鼓励她们互相交流.不过,为此FJ必须在奶 ...

  7. 获取当前的方法名字,运用线程类Thread

    得到当前方法的名字String methodName = Thread.currentThread().getStackTrace()[1].getMethodName(); getStackTrac ...

  8. 51nod 1836:战忽局的手段(期望)

    题目链接 公式比较好推 精度好难搞啊@_@ 下面记笔记@_@ ****在CodeBlocks中,输出double型变量要使用%f (参见http://bbs.csdn.net/topics/39193 ...

  9. nodejs部署配置pm2

    高大上先上部署node方式: 直接通过node app来启动,如果报错了可能直接停在整个运行, supervisor感觉只是拿来用作开发环境的. 目前似乎最常见的线上部署nodejs项目的有forev ...

  10. Yii2 $app总结

    //验证登陆 Yii::$app->user->isGuest; //当前user的id Yii::$app->user->id; //当前controller的名称 Yii: ...