题目1500:出操队形

来源:互联网 发布:苹果手机截动图软件 编辑:程序博客网 时间:2024/06/05 19:38
#include <stdio.h> #define MAX 1000001 int student[MAX];int cnt[MAX];//cnt[i]表示以i为“峰顶”的最长子序列int dp[MAX]; int BSearch(int dp[], int start, int end, int key){//搜索大于等于key的第一个元素的位置    int middle;    while (start <= end){        middle = ((end - start) >> 1) + start;        if (dp[middle] < key)            start = middle + 1;        else if (dp[middle] > key)            end = middle - 1;        else            return middle;    }    return start;} int Insert(int data, int *nMax){//找到以data为结尾的上升子序列的长度,并返回    int j = BSearch(dp, 0, *nMax, data);    if (j > *nMax){        *nMax = j;        dp[j] = data;    }    else if (dp[j-1] < data && data < dp[j]){        dp[j] = data;    }    return j;} void LIS(int n){//求以student[i]为结尾的上升子序列的长度    int i;    int nMaxLIS = 1;    dp[0] = -1;    dp[1] = student[1];    cnt[1] = 1;    for (i = 2; i <= n; ++i){        cnt[i] = Insert(student[i], &nMaxLIS);    }} void LDS(int n){//求以student[i]为开头的下降子序列的长度    int i;    int nMaxLDS = 1;    dp[0] = -1;    dp[1] = student[n];    for (i = n - 1; i >= 1; --i){        cnt[i] += Insert(student[i], &nMaxLDS) - 1;    }} int main(void){    int n, i;    int max;    while (scanf("%d", &n) != EOF){        for (i = 1; i <= n; ++i)            scanf("%d", &student[i]);        LIS(n);        LDS(n);        max = -1;        for (i = 1; i <= n; ++i)            if (max < cnt[i])                max = cnt[i];        printf("%d\n", n - max);    }     return 0;} 

0 0
原创粉丝点击