Codeforces 1114D(区间DP)
题面
分析
法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)的更多相关文章
- CodeForces 512B(区间dp)
D - Fox And Jumping Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64 ...
- codeforces 1140D(区间dp/思维题)
D. Minimum Triangulation time limit per test 2 seconds memory limit per test 256 megabytes input sta ...
- Timetable CodeForces - 946D (区间dp)
大意: n天, 每天m小时, 给定课程表, 每天的上课时间为第一个1到最后一个1, 一共可以逃k次课, 求最少上课时间. 每天显然是独立的, 对每天区间dp出逃$x$次课的最大减少时间, 再对$n$天 ...
- CodeForces - 1107E 区间DP
和紫书上的Blocks UVA - 10559几乎是同一道题,只不过是得分计算不同 不过看了半天紫书上的题才会的,当时理解不够深刻啊 不过这是一道很好区间DP题 细节看代码 #include<c ...
- CodeForces 149D 区间DP Coloring Brackets
染色有三个条件: 对于每个点来说要么不染色,要么染红色,要么染蓝色 对于每对配对的括号来说,有且只有一个一边的括号被染色 相邻的括号不能染成相同的颜色 首先可以根据给出的括号序列计算出括号的配对情况, ...
- Zuma CodeForces - 607B (区间DP)
大意: 给定字符串, 每次删除一个回文子串, 求最少多少次删完. #include <iostream> #include <cstdio> #define REP(i,a,n ...
- Recovering BST CodeForces - 1025D (区间dp, gcd)
大意: 给定$n$个数, 任意两个$gcd>1$的数间可以连边, 求是否能构造一棵BST. 数据范围比较大, 刚开始写的$O(n^3\omega(1e9))$竟然T了..优化到$O(n^3)$才 ...
- Codeforces 940 区间DP单调队列优化
A #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #def ...
- Codeforces 1114D Flood Fill (区间DP or 最长公共子序列)
题意:给你n个颜色块,颜色相同并且相邻的颜色块是互相连通的(连通块).你可以改变其中的某个颜色块的颜色,不过每次改变会把它所在的连通块的颜色也改变,问最少需要多少次操作,使得n个颜色块的颜色相同. 例 ...
随机推荐
- Page.IsPostBack
ASP.NET页面的执行顺序说明:Page_Init(页面初始化引发的事件)——Page_Load(加载页面时引发的事件)——ControlEvent(服务器控件引发的事件)——Page_UnLoad ...
- git 命令图解
git 命令图解 初始化版本库 git config user.name "lsgx" git config user.email "lsgxthink@163.co ...
- zabbix4.0短信告警配置
#!/usr/bin/env python3 import requests import sys #http://utf8.api.smschinese.cn/?Uid=USERNAME&K ...
- css中一些文本属性的用法
代码 /* text-transform用法 */ .p1 { /* 默认值 */ text-transform: none; } .p2 { /* 每个单词的首字母大写 */ text-transf ...
- go中字符串类型string的用法
示例 // 字符串类型string的用法 package main import ( "fmt" "unsafe" ) func main() { // 字符串 ...
- 记一次redis读取超时的排查过程(SADD惹的祸)
问题背景 在业务使用redis过程中,出现了read timeout 的异常. 问题排查 直接原因 运维查询redis慢查询日志,发现在异常时间节点,有redis慢查询日志,执行sadd 命令花费了1 ...
- HTML基础:用表单写一个简易登录页面
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- Maven 错误: Unknown lifecycle phase ".sourceforge.javacsv". You must specify a valid lifecycle phase or a goal
这是在Win10系统下,将Jar包手工导入进Maven本地仓库,使用PowerShell执行命令报的错. 命令如下: mvn install:install-file -Dfile=E:\Worksp ...
- POJ 3525 Most Distant Point from the Sea (半平面交)
Description The main land of Japan called Honshu is an island surrounded by the sea. In such an isla ...
- http 换成 https
UPDATE SYS_MENU M SET M.href = ( SELECT CASE WHEN substr(N.href, 0, 5) = 'http:' THEN 'https:'||subs ...