題目鏈結
o(n²)**:
1 #include 2view codeconst
int maxn = 100005;3
intinput[maxn];
4int
dec[maxn];
5int
inc[maxn];
6int cnt = 0;7
int ans_max = 0;8
int ans_need = 0;9
intmain()
1017
//初始化
18for(int i = 0;i < maxn;i++)
1923
//最長下降子串行
24for(int i = cnt- 1;i >= 0;i--)31}
32}33if(dec[i] >ans_max)
34 ans_max =dec[i];35}
36 printf("
%d\n
",ans_max);
3738
39//
最長上公升子串行
40for(int i = 0;i < cnt;i++)46}
47if(ans_need
48 ans_need =inc[i];49}
50 printf("%d"
,ans_need);
51return0;
52 }
思路:第一問:顯然求最長不上公升子串行長度即可,
第二問:求共能組成幾條最長不上公升子串行
dilworth定理:偏序集的最少反鏈劃分數等於最長鏈的長度(證明略)
就是求最長上公升子串行
但是常規dp方法只有n²複雜度,此題只有100分(滿分200)
o(nlogn)**
1 #include 2 #include 3view codeusing
namespace
std;
4const
int maxn = 1000001;5
intn;
6intm;7
intarray[maxn];
8int
tree[maxn];
9void build(int tree,int array,int node,int start,int
end)
1015
else
2526}27
void update(int tree,int array,int node,int start,int end,int idx,int
val)
2833
else
3441
else
44 tree[node] =max(tree[left_node] ,tree[right_node]);45}
46}47int query(int array,int tree,int node,int start,int end,int l,int
r)48
53else
if(start >= l && end <=r)
5458
else
if(start ==end)
62else
717273}
74int ans = 0;75
int cnt = 0;76
int max_height = 0;77
intmain()
7887 build(tree,array,1,1
,max_height);
88for(int i = 0;i < cnt;i++)
8994 printf("
%d\n
",ans);
9596 ans=0
;97 build(tree,array,1,1
,max_height);
98for(int i = 0;i < cnt;i++)
99104 printf("%d"
,ans);
105return0;
106 }
思路:1.重點是將高度值來當作線段樹下標,而不是時間序
2.通過線段樹來維護區間最長序列長度最大值
反思:線段樹處理可以將輸入資料離散化,若資料為1,2,200000,則不需要建呢麼打樹,只需要記錄相對大小1,2,3也可得到相應答案
,為什麼可以用線段樹,一知半解注意透徹理解求lis的過程。
洛谷P1020 飛彈攔截
某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。輸入飛彈依次飛來的高度 雷達給出...
洛谷 P1020 飛彈攔截
題目大意 對於乙個飛彈攔截系統 它的第一發炮彈能夠攔截任意高度的飛彈,但之後攔截的每一發炮彈都不能高於前一發的高度。輸入n發飛彈依次飛來的高度a i 計算這套系統最多能攔截多少飛彈,如果要攔截所有飛彈最少要配備多少套這種飛彈攔截系統。1 n 100 0 a i 30000 題解 p i 表示攔截了第...
洛谷 P1020 飛彈攔截
某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷 雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。輸入飛彈依次飛來的高度 雷達給出...