HDU 5773 The All-purpose Zero 2016多校第四场1010 LIS

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5773
题意:给你一个序列,找出最大上升子序列的长度,其中序列中的0可以变为任意整数(正负都可以)。
题解:对于这道题很明显是LIS,但是加多一个对0的操作。显然地,对于0,我们需要考虑把它放或者不放入最优解中。那么有什么情况是不放入0的?举个例子,现有序列4 0 5,对于0来说无论它变为什么都不能改变最终结果,但可以把0变为4或者5,也就是说我们可以把所有的0放进去。在处理不改变最终结果的0的时候,只需要用0把后面的替换掉即可,也就是例子中把0变为5,序列变成4 5 5。那么对于4 0 0 5这种情况0怎么处理?我们不能把两个0都变成5,并且必须把两个0变成不相等的两个数。也就是说所有的0都不相等。那么我们可以根据一一对应的思想(离散数学)把所有的0都变为不相等的整数。我们考虑任意相邻的两个0(下标分别为i,j),发先i、j前面0的个数刚好是相差1的。于是,我们可以将每个权值S[i]减去i前面0的个数,这样就保证了所有的0不相等,再做LIS,就能保证结果是严格递增的。
代码如下:

#include <bits/stdc++.h>
using namespace std;

int T;
int n;
int ar[100005];

int main()
{
	cin>>T;
	for(int kase=1;kase<=T;kase++)
	{
		memset(ar,0,sizeof(ar));
		int m=0;
		int tot=0;
		scanf("%d",&n);
		int a;
		for(int i=0;i<n;i++)
		{
			scanf("%d",&a);
			if(a==0)
				tot++;
			else
			{
				a-=tot;
				int p=lower_bound(ar,ar+m,a)-ar;
				ar[p]=a;
				m=max(m,p+1);
			}
		}
		printf("Case #%d: %d
",kase,m+tot);
	}
	return 0;
}


原文地址:https://www.cnblogs.com/zhuyutian/p/5815254.html