HDU-5773 The All-purpose Zero(LIS变形)

来源:互联网 发布:淘宝无法提交订单 编辑:程序博客网 时间:2024/06/05 17:07

题意:

给一组数列,其中的0可以替换为任意数字(包括负数),然后求最长上升子序列。

思路:

自己想的求一次从前向后的最长上升子序列和一次从后向前的最长下降子序列,在求得过程中贪心的更换0,以为能覆盖掉所有情况,自己也没找到否例,可是仍然不对= =,网上的思路是因为0是必定可以全选择的,对于每个非0数字,对其减掉其前面的0的个数,这样就消除了改变前面的0并且会选择它对它的影响了,所以贪心+LIS即可。

代码:

#include <bits/stdc++.h>using namespace std;const int maxn = 1e5+5;const int inf = 0x3f3f3f3f;int t, n, cnt, num;int a[maxn], dp[maxn];void work(){int ans = 0;for(int i = 1; i <= cnt; ++i){if(!ans || a[i] > dp[ans]) dp[++ans] = a[i];else{int id = lower_bound(dp+1, dp+ans+1, a[i])-dp;dp[id] = a[i];}}printf("%d\n", ans+num);}int main(){//freopen("in.txt", "r", stdin);scanf("%d", &t);for(int _ = 1; _ <= t; ++_){scanf("%d", &n);cnt = 0, num = 0;for(int i = 1; i <= n; ++i){scanf("%d", &a[i]);if(a[i] == 0) ++num;else a[++cnt] = a[i]-num;}printf("Case #%d: ", _); work();}return 0;}


继续加油~