HDU 6592 (LIS 輸出字典序最大最小)

2022-05-01 10:57:09 字數 1428 閱讀 6238

題意:給你乙個序列,讓你找長度最長的字典序最小和最大的單峰序列,單峰序列就是滿足先增後降的序列。

思路:先正著求一遍lis,再反著求一遍lis,然後用單調棧來模擬。

求字典序最小的話,首先找到第乙個頂峰,然後往前找遞減的序列中下標較小的,往後就依次找,這樣能保證字典序最小。

最大的話找到最後乙個頂峰,往前是依次找,往後是找lis中下標大的。

#includeusing

namespace

std;

#define inf 0x3f3f3f3f

const

int n = 3e5+10

;int

d[n],pos1[n],pos2[n],a[n],p[n],ans[n];

intmain()

for(int i=0 ; i<=n ; i++)

d[i]=inf;

d[0]=0

;

for(int i=n ; i>=1 ; i--)

int now=1,mx=pos1[1]+pos2[1],tot=0;///

找到最小禿頂

for(int i=2 ; i<=n ; i++)

}///找字典序最小就是正找小反找大(仔細一想是這麼一回事)

stackst;

p[pos1[now]]=a[now];///

pos1[now]--長度的尾巴是a[now]

for(int i=now-1;i>=1;i--)

while(!st.empty())

ans[++tot]=now;

///反向最大就是一直調下去

for(int i=now+1 ; i<=n ; i++)

for(int i=1;i)

printf(

"%d

",ans[i]); printf("

%d\n

",ans[tot]);

now=1; mx=pos1[1]+pos2[1]; tot=0

;

for(int i=2;i<=n;i++)

}///找字典序最大就是正找大反找小

st.push(now);

for(int i=now-1;i>=1;i--)

}while(!st.empty())

for(int i=0 ; i<=n ; i++)

p[i]=0

; p[pos2[now]]=a[now];

for(int i=now+1;i<=n;i++)

for(int i=1;i)

printf(

"%d

",ans[i]); printf("

%d\n

",ans[tot]);

}return0;

}

view code

HDU1800(貪心,lis變形)

題意 給你n個數,求這些數經過排序後能組成幾組嚴格上公升子串行。解題思路 一開始直接排序模擬,時間複雜度o n n 接著發現其實就是找序列中重複最多的元素。為什麼呢?你想,我們序列排完後假如都不重複就所有人共用1個掃把 如果某段有個元素重複,我們把它提出來,單獨一組,假如有多個重複,並且重複的元素都...

HDU 1160 (LIS 列印路徑)

還是自己對lis理解的不夠深刻,路徑長度大小不說,雖然排序了,但是肯定存在不合法的,lis在維護的時候,如果不夠增加最長子序列,就會在pos位置降值,就會出現pos位置右邊都不合法,但是這個這個長度一定存在合法的長度的序列,所以找合法的最長子序列,應該倒著尋找。第一步 排序,保證二分尋找乙個最長上公...

序列變換 HDU 5256 LIS

題意 給乙個數列,每乙個數都不相同且為整數,現求,最少需要修改多少次才能使該數列為嚴格上公升的。思路 首先,對於乙個嚴格上公升的整數數列a,一定有a i a i 1 1,所以,a i i a i 1 i 1 以此為線索,我們生成乙個新數列b i a i i,則b i b i 1 換句話說,a數列嚴格...