题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5773
题意,0可以变成任何数,问我们可以得到的最长的上升序列的长度为多少。
首先0可以变成任何数,那么最长的上升序列不一定包含所有的0,但是包含了所有的0的序列一定可以达到最长上升序列的长度,所以我们采取的策略就是把每一个数都减去它之前的0的个数,然后再进行一次LIS,最后再加上0的总个数,这样我们就能够保证一定求得的序列含有所有的0.
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1000000+5;
int a[maxn], num[maxn], dp[maxn], n;
int LIS()
{
dp[0] = -1;
int len = 0;
for(int i=1; i<=n; i++)
{
if(num[i] == num[i-1]+1) continue;
if(a[i] > dp[len]) dp[++len] = a[i];
else
{
int pos = lower_bound(dp, dp+len, a[i]) - dp;
dp[pos] = a[i];
}
}
return len;
}
int main()
{
int T, t=1;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
num[0] = 0;
for(int i=1; i<=n; i++)
{
scanf("%d", &a[i]);
num[i] = num[i-1] + (a[i]==0);
if(a[i]) a[i] -= num[i];
}
int len = LIS();
//for(int i=1; i<=len; i++) printf("%d ", dp[i]);
printf("Case #%d: %d\n", t++, len+num[n]);
}
}

针对特定问题,通过调整数值并运用最长上升子序列(LIS)算法,实现包含所有0值的最长上升序列求解。该方法先计算每个位置前的0数量,并据此调整序列数值,确保含所有0的序列可达最长。
435

被折叠的 条评论
为什么被折叠?



