題意:給你乙個序列,讓你找長度最長的字典序最小和最大的單峰序列,單峰序列就是滿足先增後降的序列。
思路:先正著求一遍lis,再反著求一遍lis,然後用單調棧來模擬。
求字典序最小的話,首先找到第乙個頂峰,然後往前找遞減的序列中下標較小的,往後就依次找,這樣能保證字典序最小。
最大的話找到最後乙個頂峰,往前是依次找,往後是找lis中下標大的。
#includeusingview codenamespace
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;
}
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數列嚴格...