您的位置:首页 > 其它

【动态规划】合唱团(动态规划)(最长上升子数列)

2016-07-29 12:26 316 查看

【动态规划】合唱团

时间限制: 1 Sec 内存限制: 64 MB
提交: 5 解决: 4[提交][状态][讨论版]

题目描述

N
位同学站成一排,墨老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。合唱队形是指这样的一种队形:设K位同学从左到右依次编号为
1,2,…,K,他们的身高分别为T1,T2,…,TK,
则他们的身高满足T1<T2<…<Ti>Ti+1>…>TK(1≤i≤K)。

你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

输入

第一行是一个整数N(2≤N≤100),表示同学的总数。第一行有n个整数,用空格分隔,第i个整数Ti(130≤Ti≤230)是第i位同学的身高(厘米)。

输出

包括一行,这一行只包含一个整数,就是最少需要几位同学出列。

样例输入

8
186 186 150 200 160 130 197 220

样例输出

4

提示

对于50%的数据,保证有n≤20;

对于全部的数据,保证有n≤100。

【分析】一个最长上升子数列和一个最长下降子数列。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <time.h>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define inf 0x3f3f3f3f
#define mod 1000000007
typedef long long ll;
using namespace std;
const int N=110;
int n,dp
,i,j,len;
int main() {
cin>>n;
int  a
;
for(int i=0; i<n; i++) {
cin>>a[i];
}
if(n==2) {
cout<<"0"<<endl;
exit(0);
}
int flag;
int maxn=0;
for(int  i=1; i<n-1; i++) {
int ans1=0,ans2=0;
memset(dp,0,sizeof(dp));
dp[0]=1;
for(int j=1; j<=i; j++) {
dp[j]=1;
for(int k=0; k<j; k++) {
if(a[j]>a[k])dp[j]=max(dp[j],dp[k]+1);
}
ans1=max(ans1,dp[j]);
}
dp[i]=1;flag=0;
for(int j=i+1; j<n; j++) {
dp[j]=1;
for(int k=i; k<j; k++) {
if(a[k]>a[j])dp[j]=max(dp[j],dp[k]+1);
}
ans2=max(ans2,dp[j]);
}
if(ans1+ans2>maxn){
maxn=max(maxn,ans1+ans2);
if(ans1==1||ans2==1)flag=1;
}
}
if(!flag)cout<<n-maxn+1<<endl;
else cout<<n-maxn<<endl;
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: