給出乙個題目背景,題源:洛谷p1020
二維偏序跟多理解可以參考博文
某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。某天,雷達捕捉到敵國的飛彈來襲。由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈。
輸入飛彈依次飛來的高度(雷達給出的高度資料是\(\le 50000\)的正整數),計算這套系統最多能攔截多少飛彈,如果要攔截所有飛彈最少要配備多少套這種飛彈攔截系統。
11行,若干個整數(個數\(\le 100000\))
22行,每行乙個整數,第乙個數字表示這套系統最多能攔截多少飛彈,第二個數字表示如果要攔截所有飛彈最少要配備多少套這種飛彈攔截系統。
結論:這題只需要求乙個不上公升序列長度和乙個上公升序列長度。
說明:前者十分好理解,對於後者,這裡這樣考慮:因為每套飛彈系統可以攔截乙個不公升序的序列,那麼最長上公升子串行一定是最少的飛彈系統的個數(這個應該好理解),而使用最長上公升序列的每乙個值,作為開始攔截的高度,可以滿足全部攔截,故得出開始的結論。(不算嚴謹的證明,但是比較好理解)
複雜度:\(n*log(n)\),常見的最長上公升子串行演算法,當然\(n^2\)的解法更容易理解,但這種解法也很常見了。
對於求不公升序列,把原陣列倒序,reverse即可,然後使之可以滿足相等的條件。
#include #includeusing namespace std;
const int n=1e5+10;
const int inf=0x3f3f3f3f;
int a[n];
int b[n];
int dp[n];
int n=0;
int get_max1()
cout《常規用法,維護最大值。
#includeusing namespace std;
const int maxn=5e4+10;
const int n=1e5+10;
int a[n];
int b[n];
int bit[maxn];
int max;
int lowbit(int x)
int sum(int x)
return ans;
}//更新包含x的全部區間的最大值
int update(int x,int v)
}int main()
int ans=0;
int res=0;//最長上公升子串行
for(int i=0;imemset(bit,0,sizeof(bit));
reverse(a,a+cur);
//for(int i=0;iint res1=0;//最長不公升子串行
ans=0;
for(int i=0;iprintf("%d\n%d\n",res1,res);
return 0;
}
最長上公升子串行 滑雪(二維)
michael喜歡滑雪百這並不奇怪,因為滑雪的確很刺激。可是為了獲得速度,滑的區域必須向下傾斜,而且當你滑到坡底,你不得不再次走上坡或者等待公升降機來載你。michael想知道載乙個區域中最長底滑坡。區域由乙個二維陣列給出。陣列的每個數字代表點的高度。下面是乙個例子 1 2 3 4 5 16 17 ...
最長上公升子串行的兩種寫法
乙個序列a 找出它的最長上公升子串行的個數,很明顯是4個,可以是,或者。他有兩種實現的方法 第一種是時間複雜度為o n 2 的演算法 include include include include using namespace std intmain int n sizeof a sizeof i...
最長上公升子串行的兩種解法
問題描述 乙個數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列 a1,a2,an 我們可以得到一些上公升的子串行 ai1,ai2,aik 這裡1 i1 i2 ik n。比如,對於序列 1,7,3,5,9,4,8 有它的一些上公升子串行,如 1,7 3,4,8 等等...