P1020 导弹拦截———— 动态规划,树状数组

题解:本题主要考查动态规划,求最长不上升子序列和最长上升子序列。因为数据规模大,就用树状数组来维护。
代码如下:

 #include
#include
#include
#include 
using namespace std;
int n,m,maxn=-123456;
int tree[2342567],a[2345678];
int lowbit(int k)
{
     return k&-k;	
}
void add(int x,int k)
{
	while(x<=maxn)
	{
		tree[x]=max(tree[x],k);//维护最大值
		x+=lowbit(x);
	}
}
int search(int x)
{
	int ans=0;
	while(x!=0)
	{
		ans=max(ans,tree[x]);求最长不上升子序列的长度的最大值 
		x-=lowbit(x);
	}
	return ans;
}
int main()
{
	int ans1=0,ans2=0;
    while(scanf("%d",&a[++n])!=EOF) maxn=max(maxn,a[n]);
	n--;
	for(int i=n;i>=1;i--)
	{
		int q=search(a[i])+1;
		add(a[i],q);
		ans1=max(ans1,q);
	}
    printf("%d\n",ans1);
	memset(tree,0,sizeof(tree));
	for(int i=1;i<=n;i++)
    {
		int q=search(a[i]-1)+1;//注意此处为什么要-1
		add(a[i],q);
		ans2=max(ans2,q);
	}
	printf("%d\n",ans2);
	return 0;
}

你可能感兴趣的:(DP,线段树)