您的位置:首页 > 大数据 > 人工智能

最长递增子序列 ( LIS )——The All-purpose Zero ( HDU 5773 ) ( 2016 Multi-University Training Contest 4 1010 )

2016-07-28 22:09 447 查看
题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5773

分析:

给出N个数,其中0可以被替换成 0 ~ 9 的任何数字,问替换后这N个数的最长递增子序列的长度为多少?

题解:

为了保证严格递增,我们把每一个数都减去这个数之前的0的个数,然后去掉0,做一次LIS求出长度,然后加上0的个数就是原来数列的LIS长度了。

LIS模板:

int DP[Maxn];
int LIS(int arr[],int n)//arr为数列,n为数列长度,数列从0开始。
{
memset(DP, 0, sizeof(DP));
int i,top,mid,low,high;
top = 0;
DP[0] = -1;
for(i=0;i<n;i++)
{
if(arr[i]>DP[top])
DP[++top] = arr[i];
else
{
low = 1;
high = top;
while(low <= high)
{
mid = (low + high)/2;
if(arr[i] > DP[mid])
low = mid + 1;
else
high = mid - 1;
}
DP[low] = arr[i];
}
}
return top;
}


AC代码:

#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#define Maxn 112345
using namespace std;
int N;
int a[Maxn];
int DP[Maxn];
int LIS(int arr[],int n)
{
memset(DP, 0, sizeof(DP));
int i,top,mid,low,high;
top = 0;
DP[0] = -1;
for(i=0;i<n;i++)
{
if(arr[i]>DP[top])
DP[++top] = arr[i];
else
{
low = 1;
high = top;
while(low <= high)
{
mid = (low + high)/2;
if(arr[i] > DP[mid])
low = mid + 1;
else
high = mid - 1;
}
DP[low] = arr[i];
}
}
return top;
}
int main()
{
int T;
scanf("%d", &T);
int ii =1;
while(T--)
{
memset(a, 0, sizeof(a));
scanf("%d", &N);
int Zero = 0;
int index = 0;
for(int i=0; i<N;i++)
{
int x;
scanf("%d", &x);
if(x)  a[index++] = x - Zero;
else Zero++;
}
//cout << LIS(a,index) <<endl;
printf("Case #%d: %d\n", ii++, LIS(a,index)+Zero );
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  LIS ACM 算法 2016多校