• 洛谷 P1091 合唱队形


    洛谷 P1091 合唱队形

    $$传送门在这里呀$$


    题目描述

    (N)位同学站成一排,音乐老师要请其中的((N-K))位同学出列,使得剩下的(K)位同学排成合唱队形。

    合唱队形是指这样的一种队形:设K位同学从左到右依次编号为(1,2,…,K),他们的身高分别为(T_1,T_2,…,T_K), 则他们的身高满足(T_1<...<T_i,T_{i+1}>…>T_K(1 le i le K))

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


    输入输出格式

    输入格式:

    共二行。

    第一行是一个整数(N(2 le N le 100)),表示同学的总数。

    第二行有(n)个整数,用空格分隔,第(i)个整数(T_i(130 le T_i le 230))是第(i)位同学的身高(厘米)。

    输出格式:

    一个整数,最少需要几位同学出列。


    输入输出样例

    输入样例#1:

    8
    186 186 150 200 160 130 197 220

    输出样例#1:

    4


    说明

    对于(50%)的数据,保证有(n le 20)

    对于全部的数据,保证有(n le 100)


    思路

    此题是动态规划的基础题之一,我太lj了,最后想不出来怎么处理来得到最大值qwq

    和日常生活中照照片一样,(为了美观),这个题要求的合唱队形要求两边低,中间高,也就是前一段是递增的,后一段是递减的,注意:

    并不一定正好分为左右人数相等的两半.

    从左边开始,求出到每个数存在的最长上升子序列,然后再从右边做一次一样的操作,这样就能求出每个数字所在的上升子序列与下降子序列,分别用两个数组b和c记录

    然后for循环进行枚举,求出b[i]+c[i]的最大值,最大值所对应的i就是i作为最高点时,合唱队里留下的人最多,最后结果就是n-maxn+1,因为i位置的同学在计算maxn的时候算了两边,所以加1。


    代码

    #include<bits/stdc++.h>
    #define N 10100
    #define INF 0x7f
    using namespace std;
    
    int a[N],b[N],c[N];
    
    int main() {
    	int n;
    	scanf("%d",&n);
    	for(int i=1; i<=n; i++) {
    		scanf("%d",&a[i]);
    	}
    	for(int i=1; i<=n; i++) {
    		b[i]=1;
    		for(int j=1; j<i; j++) {
    			if(a[i]>a[j]&&b[i]<b[j]+1) {
    				b[i]=b[j]+1;
    			}
    		}
    	}
    	for(int i=n; i>0; i--) {
    		c[i]=1;
    		for(int j=n; j>i; j--) {
    			if(a[i]>a[j]&&c[i]<c[j]+1) {
    				c[i]=c[j]+1;
    			}
    		}
    	}
    	int maxn=-INF;
    	for(int i=1; i<=n; i++) {
    		if (b[i]+c[i]>maxn)
    			maxn=b[i]+c[i];
    	}
    	maxn=n-maxn+1;
    	cout<<maxn<<'
    ';
    	return 0;
    }
    
  • 相关阅读:
    信号处理引发的cpu高
    两个混淆的用户锁定
    一段获取权限的脚本
    AF_INET 和PF_INET区别;AF_LOCAL PF_LOCAL 区别.
    一个三目运算符问题
    nginx cpu高排查
    mmap 测试的一些坑
    哈希——布隆过滤器 查黑名单(大数据 100亿数据)
    哈希——设计RandomPool结构
    哈希
  • 原文地址:https://www.cnblogs.com/loceaner/p/10773032.html
Copyright © 2020-2023  润新知