一道线性dp,和前天写的是一样的,今天准备在学一学二分写法
AC代码:
#include<bits/stdc++.h>
using namespace std;
//最大单调递减序列
#define maxn 1005
int dp[maxn];
int a[maxn];
int n;
void slove_dp()
{
for(int i=1;i<=n;i++)
{ dp[i]=1;
for(int j=1;j<i;j++)
{
if(a[i]<a[j])
{
dp[i]=max(dp[i],dp[j]+1);
}
}
}
int maxx=-1;
for(int i=1;i<=n;i++)
{
if(maxx<dp[i])
maxx=dp[i];
}
printf("%d\n",maxx);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(a,0,sizeof(a));
memset(dp,0,sizeof(dp));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
slove_dp();
}
}
二分优化AC代码:
#include<bits/stdc++.h>
using namespace std;
//二分优化最长递增子序列
#define maxn 10005
int Stack[maxn];
int a[maxn];
int n;
int lower_ans(int l,int r,int i)//返回刚好比l大1的位置
{
while(l<=r)
{
int mid=(l+r)/2;
if(a[i]>=Stack[mid])
{
r=mid-1;
}
else
{
l=mid+1;
}
}
return l;
}
void slove_dp()
{
int top=1;
Stack[top]=a[0];
for(int i=1; i<n; i++)
{
if(Stack[top]>a[i])
{
Stack[++top]=a[i];//保证Stack[]单调
}
else
{
Stack[lower_ans(1,top,i)]=a[i];
}
}
printf("%d\n",top);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
memset(Stack,0,sizeof(Stack));
for(int i=0; i<n; i++)
{
scanf("%d",&a[i]);
}
slove_dp();
}
}