题意:士兵拍成一行,让最少的士兵出列,使得每个士兵都能看到至少一个最边上的士兵(中间某个人能看到最边上的士兵的条件是该士兵的身高一定强大于他某一边所有人的身高),身高序列可以是这样:1 2 3 4 5 4 3 2 1 或者 1 2 3 4 5 5 4 3 2 1
本题不是难题,但是细节处理是很恼火的(个人觉得),例如处理第二种身高序列
例如:
8
3 4 5 1 2 5 4 3
数据来源于discuss。
做法:记录每个人左边的最大升序列中的人数(注意:他自己也算一个并且身高严格递增),记录每个人右边的最大严格降序列的人数,也包括他自己。
然后代码中有第二种身高序列的处理。
#include <iostream>
#include <cmath>
using namespace std;
#define N 1002
int up[N], down[N];
double h[N];
int main()
{
int n, i, j;
scanf("%d", &n);
for(i = 1; i <= n; i++)
scanf("%lf", &h[i]);
for(i = 1; i <= n; i++)
{
up[i] = 1;
for(j = i-1; j >= 1; j--)
if(h[i] > h[j]){
if(up[i] <= up[j])
up[i] = up[j] + 1;
}
}
for(i = n; i >= 1; i--)
{
down[i] = 1;
for(j = i+1; j <= n; j++)
if(h[j] < h[i]){
if(down[i] <= down[j])
down[i] = down[j] + 1;
}
}
int tmp = 0;
for(i = 1; i < n; i++) //处理答案为第二种情况时
for(j = i+1; j <= n; j++)
if(up[i] + down[j] > tmp)
tmp = up[i] + down[j];
printf("%d\n", n - tmp);
//system("pause");
return 0;
}