乙個dp題。複雜度是n*logn(n是for迴圈從0到n遍歷,logn是二分查詢)
思路:預處理:
從前往後掃一遍,更新pre陣列(記錄每乙個元素是子串中連續上公升的第幾個,如果a[i]>a[i-1],則a[i]=1.否則a[i]=a[i-1]+1,a[i]是題目給的)
從後往前掃一遍,更新aft陣列(記錄每乙個元素是子串中連續下降的第幾個,如果a[i]>a[i+1],則a[i]=1.否則a[i]=a[i+1]+1)
二分查詢:
初始化dp陣列為正無窮(0x3f3f3f3f3f3f3f)
從前向後遍歷a[i],更新dp陣列,dp陣列是乙個用來記錄長度為i的連續上公升子串的最後乙個元素的最小值的陣列。dp[pre[i]]=min(dp[i],a[i]).這樣就可得到當前連續上公升子串長度的最後乙個元素的最小值。
拼接:對於當前i,有最小的dp[1],dp[2]......dp[i-1],(在**中,把拼接這一步放在更新dp陣列前).然後我們用lower_bound在dp陣列中尋找到乙個比當前a[i]大一點的dp[j],(如果能找到a[i],lower_bound返回的是a[i]座標,否則返回比a[i]大一點的那個元素的座標),在dp陣列中,小於dp[j]而大於dp陣列中其他元素的那個元素一定小於a[i]。例如:
12365 :dp[1]=1 dp[2]=2,dp[3]=3,dp[4]=6,dp[5]=0x3f3f3f3f3f3f3f.對於a[5],二分找到的大於等於a[5]的dp[j]=6,j=4
ans=max(ans,j-1+aft[i]),其中j-1+aft[i]=4-1+1=4
123556:dp[1]=1,dp[2]=2,dp[3]=3,dp[4]=4,dp[5]=0x3f3f3f3f3f3f3f.對於a[5],二分找到的大於等於它的dp[j]=5,j=4
ans=max(ans,j-1+aft[i]),其中j-1+aft[i]=4-1+2=5
12367567:dp[1]=1,dp[2]=2,dp[3]=3,dp[4]=6,dp[5]=0x3f3f3f3f3f3f3f.dp[6]=0x3f3f3f3f3f3f3f,dp[7]=0x3f3f3f3f3f3f3f....對於a[5],二分找到的大於等於它的dp[j]=6,j=4
ans=max(ans,j-1+aft[i]),其中j-1+aft[i]=4-1+3=6
**:
#include#include#include#include#include#include#include#include#define maxn 200008
#define ll long long
#define rpg(i,a,b) for(int i=(a);i<(b);i++)
using namespace std;
int aft[maxn],pre[maxn];
ll dp[maxn],a[maxn];
int main()
aft[n-1]=1;
for(int i=n-2; i>=0; i--)
int ans=0;
rpg(i,0,n+5)
dp[i]=0x3f3f3f3f3f3f3f3f;
rpg(i,0,n)
printf("%d\n",ans);
}return 0;
}
uvalive3971(二分 貪心)
題目的意思是 你要去買一台電腦,然後有很多種零件,你每種零件買乙個 零件給出的的資訊有種類,名字,質量.你組裝的電腦的質量,取決於你的零件中質量最差的,也就是你要讓最差值盡量大,但是 不能超出你的budget,也就是你有的錢.把零件按質量從大到小排,然後從大到小判斷這個質量能不能作為最小值.知道找到...
迭代二分查詢二分查詢
在寫這篇文章之前,已經寫過了幾篇關於改迭代二分查詢主題的文章,想要了解的朋友可以去翻一下之前的文章 bentley在他的著作 writing correct programs 中寫道,90 的計算機專家不能在2小時內寫出完整確正的二分搜尋演算法。難怪有人說,二分查詢道理單簡,甚至小學生都能明確。不過...
UVALive 3635 Pie 二分答案
題意 有f 1個人來分n個圓形派,要求每個人得到的派必須是一整塊的,不能是幾塊拼在一起的,而且每個人得到的派的大小一樣,問每個人最多能得到的派的面積。思路 一開始拿到題目,我嘗試推公式,後來覺得實在找不到規律,看了書,發現是二分答案,把問題轉化為 是否可以讓每個人的到面積為x的派 因為派是不可以拼起...