20200915 day10 刷题记录

1 1065 1284 导弹拦截

最长上升子序列

POJ2533

题意显然。
子序列:序列\(\{a_n\}\),则其一个子序列是存在一些数\(j_x\),使得\(1\le j_1<j_2<...\le n\),构成子序列\(\{a_j\}\)

题解

\(\text{O}(n^2)\)

\(f_i\)表示以\(a_i\)结尾的上升子序列最长为多少。初始化显然每个\(f都为1\)。我们从\(1\)~\(i-1\)枚举\(f_j\),当\(a_j<a_i\)时,\(f_i=max(f_i,f_j+1)\)
最后我们输出最大的\(f_i\)即可。

\(O(n\log n)\)

设原数组为\(a_n\),设\(f_i\)表示长度为\(i\)的序列中最长上升的最小值(他是原数组的数值)

如果a[i]>dp[len],len表示当前LIS最长长度,就直接放入末尾
否则,在dp数组中寻找第一个大于等于a[i]的位置,把他替换成a[i],这样的话dp[len]的数值变得稍小,可以更好地在后面接上升序列

for(int i=1; i<=n; i++){
        if(a[i]>dp[len]) dp[++len]=a[i];
        else{
            dp[lower_bound(dp+1,dp+1+len,a[i])-dp]=a[i];
        }
    }

2 1087 挖地雷

拓扑排序

posted @ 2020-09-15 15:42  刘子闻  阅读(70)  评论(0编辑  收藏  举报