1. 题⽬链接:DP16合唱队形
2. 题⽬描述:
3. 解法:
算法思路:
最⻓上升⼦序列模型。
C++算法代码:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
//初始化
int n;
cin>>n;
vector<int>temp(n);
for(int i=0;i<n;i++)
{
cin>>temp[i];
}
vector<int>l(n,1); //从左往右的最长递增序列
vector<int>r(n,1); //从右往左的最长递增序列 —— 最长递减序列
//填表
for(int i=1;i<n;i++)
{
for(int j=0;j<i;j++)
{
if(temp[i]>temp[j])
{
l[i]=max(l[j]+1,l[i]);
}
}
}
for(int i=n-1;i>=0;i--)
{
for(int j=i+1;j<n;j++)
{
if(temp[i]>temp[j])
{
r[i]=max(r[j]+1,r[i]);
}
}
}
//输出
int ret=0; //找出最长的合法序列
for(int i=0;i<n;i++)
{
ret=max(ret,l[i]+r[i]-1);
}
cout<<n-ret; //输出最少的修改个数
return 0;
}
Java算法代码:
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] arr = new int[n + 1];
for (int i = 1; i <= n; i++)
{
arr[i] = in.nextInt();
}
int[] f = new int[n + 1];
int[] g = new int[n + 1];
// 从左往右
for (int i = 1; i <= n; i++)
{
f[i] = 1;
for (int j = 1; j < i; j++)
{
if (arr[i] > arr[j])
{
f[i] = Math.max(f[i], f[j] + 1);
}
}
}
// 从右往左
for (int i = n; i >= 1; i--)
{
g[i] = 1;
for (int j = i + 1; j <= n; j++)
{
if (arr[i] > arr[j])
{
g[i] = Math.max(g[i], g[j] + 1);
}
}
}
int len = 0;
for (int i = 1; i <= n; i++)
{
len = Math.max(len, f[i] + g[i] - 1);
}
System.out.println(n - len);
}
}