题目大意:找到队列中不符合非升(降)序趋势的编号个数,
分别判断升序跟降序的个数,最后取最小。
两种方法:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#define maxn 30005
int n;
int cow[maxn];
int f[maxn][5];
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &cow[i]);
memset(f, 0, sizeof(f));
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= 3; j++)
{
f[i][j] = f[i - 1][1];
for (int k = 2; k <= j; k++)
f[i][j] = min(f[i][j], f[i - 1][k]);
if (cow[i] != j)
f[i][j]++;
}
}
int ans = n;
for (int i = 1; i <= 3; i++)
ans = min(ans, f[n][i]);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= 3; j++)
{
f[i][j] = f[i - 1][3];
for (int k = 2; k >= j; k--)
f[i][j] = min(f[i][j], f[i - 1][k]);
if (cow[i] != j)
f[i][j]++;
}
}
for (int i = 1; i <= 3; i++)
ans = min(ans, f[n][i]);
printf("%d\n", ans);
return 0;
}
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int sup=30005;
int LDS[sup];//不升
int LIS[sup];//不降
int dp[sup];
int n;
int bsearch(int beg,int end,int p)
{
int mid;
while(beg<=end)
{
mid=(beg&end)+((beg^end)>>1);
if(dp[mid]<=p)
beg=mid+1;
else if(dp[mid]>p)
end=mid-1;
}
return beg;
}
int lis()
{
int i;
int top=-1;
for(i=0;i<n;++i)
{
if(dp[top==-1?0:top]<=LIS[i])
dp[++top]=LIS[i];
else if(dp[top==-1?0:top]>LIS[i])
dp[bsearch(0,top,LIS[i])]=LIS[i];
}
return n-top-1;
}
int lds()
{
int i,top=-1;
for(i=0;i<n;++i)
{
if(dp[top==-1?0:top]<=LDS[i])
dp[++top]=LDS[i];
else if(dp[top==-1?0:top]>LDS[i])
dp[bsearch(0,top,LDS[i])]=LDS[i];
}
return n-top-1;
}
int main()
{
int i;
scanf("%d",&n);
for(i=0;i<n;++i)
{
scanf("%d",&LIS[i]);
LDS[n-i-1]=LIS[i];
}
int ans=lis();
fill(dp,dp+sup,0);
int t=lds();
ans=ans<t?ans:t;
if(ans!=-1)
printf("%d\n",ans);
else
printf("0\n");
return 0;
}
时间: 2024-10-08 14:19:42