划分数列
解题思路
设 f i f_i fi 表示从一到 i 最少可以划分的段数
则有转移方程
f i = m i n ( f b i − 1 , f c i − 1 ) + 1 f_i=min(f_{b_i}−1,f_{c_i}−1)+1 fi=min(fbi−1,fci−1)+1
b i b_i bi 表示以 i 结尾单调递增的一段的起点
c i c_i ci 表示以 i 结尾单调递减的一段的起点
AC代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,last,a,b[100005],c[100005],f[100005];
int main()
{
scanf("%d%d",&n,&last);
b[1]=c[1]=1;//初值
for(int i=2;i<=n;i++)//预处理
{
scanf("%d",&a);
if(a>=last)b[i]=b[i-1];
else b[i]=i;
if(a<=last)c[i]=c[i-1];
else c[i]=i;
last=a;
}
memset(f,0x7fff,sizeof(f));//初值
f[0]=f[1]=0;
for(int i=1;i<=n;i++)//递推
f[i]=min(f[b[i]-1]+1,f[c[i]-1]+1);
printf("%d",f[n]);
return 0;
}