題意: 乙個長度為n的陣列,可以從裡面刪除長度任意(可以為0)的連續子串行,使得之後的最長的連續上公升子串行長度最大。
最初的想法是遍歷兩次陣列,進行預處理。得出f,g。
f[i] g[i] 分別為一i為結尾和以i為開頭的最長連續上公升子串行。之後列舉i,j 得到在num[i] < num[j] 的情況下得到max( f[i] + g[j] ),即為答案。
複雜度為o(n ^ 2)
然而這題的資料量 要求使用o(nlogn)的複雜度,所以考慮如何優化。
然而預處理的已經不可能再進行優化。所以考慮在列舉的時候進行優化。
這可看到在列舉i的時候可以看到,對於某個i 有乙個i』 。i, i』< j 且num[i』] < num[i] 而且 f[i』] > f[i]。這樣對於i來說不論如何 最優解絕對不會由i來組合,所以i可以拋棄。
在列舉j的時候,i 的集合是動態的,所以用stl的set完成這個插入刪除和查詢。
**如下
#include
#include
#include
#include
using
namespace
std;
const
int maxn = 200005;
typedef pair pii;
int num[maxn],f[maxn],g[maxn];
int n;
void initial()
for(int i = n - 1;i > 0;--i)
}bool slove()
if(keep)}}
printf("%d\n",ans);
}int main()
return
0;}
uva 1471 動態維護序列二元組
本題的題意就是從長為n的串中擷取一段,把剩下的兩端拼接起來構成乙個可以夠成的最長連續上公升子串行。首先本題若直接按照題意來先列舉擷取的起點和終點在數一數就需要o n 3 時間複雜度。n為2 10 5太大。預處理就可以避免數一數 以f i 表示以i位置為開頭的連續上公升序列的長度。g i 表示以i位置...
用分析函式優化標量子查詢
原語句如下 select ii.case when select count 1 from ii where ii.id 0 and ii.flag 2 and ii.i code ii.i code and ii.c id not in select c id from c where ig na...
懶人的福利 教你用set維護斜率優化凸包
斜率優化題目大家肯定都做得不少了,有一些題目查詢插入點的x座標和查詢斜率都不單調,這樣就需要維護動態凸包並二分斜率。例如bzoj1492 常規的做法是cdq分治或手寫平衡樹維護凸包,然而如果我不願意寫分治,也懶得打平衡樹,怎麼辦呢?沒關係,今天我告訴你怎麼用乙個set維護這種凸包。首先orzlh,沒...