HDU-5772 贪心策略+LIS [2016多校]

给定大小为N的序列,当某个元素为0时,可将其替换成任意整数;问能够得到的最长递增子序列长度。

贪心策略基于这样一个性质:
最优子序列是包含了所有原来为0的元素的子序列。
证明可以用反证法,设一个最长子序列中不包含某个0元素,那么我们必然可以:

  1. 用这个0元素替换它前面或者后面的已选非0元素,子序列长度不变;
  2. 子序列增加这个0元素,子序列长度变长;

无论如何都不会比原来的差。

所以A[i], A[j] (i

即:A[j]-A[i]>SUM[j]-SUM[i] (SUM[i]表示i号元素之前有多少个0元素)
转化一下即是:A[j]-SUM[j]>A[i]-SUM[i]
由以上这个式子,我们可以直接将所有A[i]修改为A[i]-SUM[i]之后,直接计算非0元素的LIS长度并加上0元素个数即可,非常妙。

#include 
#include 
#include 
#include 
using namespace std;
#define N 1050
int d[N];
int main(){
    int t,kase=0;
    cin>>t;
    while(t--){
        int n,zeros=0;
        cin>>n;
        vector a;
        for (int i=0;i>x;
            if (x) a.push_back(x-zeros);
            else zeros++;
        }

        int cnt = 0;
        for (int i=0;id[cnt-1]) d[cnt++] = a[i];
            int pos = lower_bound(d, d+cnt, a[i]) - d;
            d[pos] = a[i];
        }
        printf("Case #%d: %d\n", ++kase, cnt+zeros);
    }

    return 0;
}

你可能感兴趣的:(HDU-5772 贪心策略+LIS [2016多校])