日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

最长上升子序列三种模板(n^2模板,二分模板,树状数组模板)

發布時間:2023/12/15 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最长上升子序列三种模板(n^2模板,二分模板,树状数组模板) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最長上升子序列(LIS)是動態規劃的入門。總結下來,經常用的模板一共有三種,分別為n^2模板,二分模板,樹狀數組模板。

n^2模板代碼如下:

//n^2算法,本質就是dp,采用二重循環的方式。對于數據量比較少的情況,是可以接受的。該模板求的是嚴格遞增序列的最長長度。 #include<bits/stdc++.h> #define ll long long using namespace std;const int maxx=4e4+100; int a[maxx],c[maxx]; int n;int main() {int t;scanf("%d",&t);while(t--){scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&a[i]);int ans=0;for(int i=1;i<=n;i++){c[i]=1;for(int j=1;j<i;j++){if(a[i]>a[j]) c[i]=max(c[i],c[j]+1);}ans=max(ans,c[i]);}printf("%d\n",ans);}return 0; }

二分模板代碼如下:

//二分模板本質上是貪心,一重循環和dp一樣,但是第二重,找第一個大于等于該數的時候,采用的是二分策略,降到了nlogn的復雜度。該模板求得是嚴格遞增序列的最大長度。 #include<bits/stdc++.h> #define ll long long using namespace std;const int maxx=4e4+100; int a[maxx],c[maxx]; int n;int main() {int t;scanf("%d",&t);while(t--){scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&a[i]);int len=0;memset(c,0,sizeof(c));for(int i=1;i<=n;i++){int pos=lower_bound(c+1,c+1+len,a[i])-c;if(pos>len) c[++len]=a[i];else c[pos]=a[i];}printf("%d\n",len);}return 0; }

樹狀數組模板代碼如下:

//樹狀數組模板,理解起來比較困難,但是也是求LIS的一個比較有用的工具。要注意的是,這個模板沒有去重,因此嚴格意義上說,求得是最長非下降序列的長度。去重之后就是嚴格遞增序列的長度了。 #include<bits/stdc++.h> #define ll long long using namespace std;const int maxx=4e4+100; struct node{int v,pos;bool operator<(const node &a)const{return v<a.v;} }p[maxx]; int c[maxx]; int n;inline int lowbit(int x){return x&-x;} inline void update(int x,int v) {while(x<maxx){c[x]=max(c[x],v);x+=lowbit(x);} } inline int query(int x) {int ans=-1;while(x){ans=max(ans,c[x]);x-=lowbit(x);}return ans; } int main() {int t;scanf("%d",&t);while(t--){memset(c,0,sizeof(c));scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&p[i].v),p[i].pos=i;sort(p+1,p+1+n);int ans=0;for(int i=1;i<=n;i++){int _max=query(p[i].pos);update(p[i].pos,++_max);ans=max(ans,_max);}printf("%d\n",ans);}return 0; }

一道hdu的模板題,Bridging signals HDU - 1950
利用二分模板或者樹狀數組都可以過。
用時如下:
二分:

樹狀數組:

二分還是略快一點點的。。而且也比較好理解。
努力加油a啊,(o)/~

總結

以上是生活随笔為你收集整理的最长上升子序列三种模板(n^2模板,二分模板,树状数组模板)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。