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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

2021牛客暑期多校训练营2 G.League of Legends(转化+单调队列)

發布時間:2023/12/3 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2021牛客暑期多校训练营2 G.League of Legends(转化+单调队列) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

G.League of Legends

Zechariah_2001題解
對于可以包含其他區間的大區間,要使得答案最優無非就是兩種分組方式:單獨一組或者與被包含的區間一組。單獨一組那么貢獻就是區間長度;如果說與被包含的區間一組,對答案貢獻為0,因為根據題意,如果有多個區間,添加區間實際上是添加限制,不會是當前答案變優。

把上面的覆蓋別的區間的區間出去后,剩下的區間按照左端點升序排序后不難發現右端點同樣也會升序排列。

設計dp:

狀態表示:fj,if_{j,i}fj,i?考慮前iii個區間,分成jjj組的最大值
狀態轉移:fj,i=max?{fj?1,k?1+Rk?Li},Rk>Lif_{j,i}=\max\{f_{j-1,k-1}+\text R_k-\text L_i\},\text R_k>\text L_ifj,i?=max{fj?1,k?1?+Rk??Li?},Rk?>Li?

Rk>Li\text R_k>\text L_iRk?>Li?這個限制保證每組至少玩1分鐘游戲

如果沒有上述現之,可以搞一個前綴的max?{fj?1,k?1+Rk}\max\{f_{j-1,k-1}+\text R_k\}max{fj?1,k?1?+Rk?}優化轉移,加上此限制后需要單調隊列優化轉移。

Code1 暴力

895ms 竟然也能過???

#include<bits/stdc++.h> using namespace std; using ll=long long; using pii=pair<int,int>; using pli=pair<ll,int>; constexpr ll mod=1e9+7; //============================= int rd() {int res=0;char ch=getchar();while(!isdigit(ch)) ch=getchar();while( isdigit(ch)) res=(res<<1)+(res<<3)+(ch^48),ch=getchar();return res; } const int N=5010; int n,m; struct node {int l,r;bool operator<(const node&o)const{return l<o.l||l==o.l&&r>o.r;} }a[N],b[N]; int seg[N],cnt,tot; int f[N][N];// f[j][i] 前i個分成j組 int main() {n=rd(),m=rd();for(int i=1;i<=n;i++) b[i].l=rd(),b[i].r=rd();sort(b+1,b+1+n);int maxr=0x3f3f3f3f;for(int i=n;i;i--){if(b[i].r>=maxr) //能夠覆蓋別的線段seg[++tot]=b[i].r-b[i].l;elsemaxr=b[i].r,a[++cnt]=b[i];}sort(a+1,a+1+cnt);memset(f,-0x3f,sizeof f);f[0][0]=0;for(int j=1;j<=cnt;j++)for(int i=j;i<=cnt;i++)for(int k=1;k<=i;k++)if(a[k].r>a[i].l)f[j][i]=max(f[j][i],f[j-1][k-1]+a[k].r-a[i].l);sort(seg+1,seg+1+tot,greater<int>());int ans=0,sum=0;for(int i=0;i<=min(m,tot);i++){sum+=seg[i];if(f[m-i][cnt]!=-1) ans=max(ans,f[m-i][cnt]+sum);}cout<<ans<<'\n';return 0; }

Code2 單調隊列

83ms

#include<bits/stdc++.h> using namespace std; using ll=long long; using pii=pair<int,int>; using pli=pair<ll,int>; constexpr ll mod=1e9+7; //============================= int rd() {int res=0;char ch=getchar();while(!isdigit(ch)) ch=getchar();while( isdigit(ch)) res=(res<<1)+(res<<3)+(ch^48),ch=getchar();return res; } const int N=5010; int n,m; struct node {int l,r;bool operator<(const node&o)const{return l<o.l||l==o.l&&r>o.r;} }a[N],b[N]; int seg[N],cnt,tot; int f[N][N];// f[j][i] 前i個分成j組 int q[N]; int main() {n=rd(),m=rd();for(int i=1;i<=n;i++) b[i].l=rd(),b[i].r=rd();sort(b+1,b+1+n);int maxr=0x3f3f3f3f;for(int i=n;i;i--){if(b[i].r>=maxr) //能夠覆蓋別的線段seg[++tot]=b[i].r-b[i].l;elsemaxr=b[i].r,a[++cnt]=b[i];}sort(a+1,a+1+cnt);memset(f,-0x3f,sizeof f);f[0][0]=0;// f[j-1][k-1] + a[k].r a[k].r>a[i].l && k<=ifor(int j=1;j<=cnt;j++){int tt=-1,hh=0;for(int i=1;i<j;i++){while(hh<=tt){int k=q[tt];if(f[j-1][i-1]+a[i].r>=f[j-1][k-1]+a[k].r) --tt;else break;}q[++tt]=i;}for(int i=j;i<=cnt;i++){while(hh<=tt) {int k=q[hh];if(a[k].r<=a[i].l) hh++;else break;}while(hh<=tt){int k=q[tt];if(f[j-1][i-1]+a[i].r>=f[j-1][k-1]+a[k].r) --tt;else break;}q[++tt]=i;int k=q[hh];f[j][i]=max(f[j][i],f[j-1][k-1]+a[k].r-a[i].l);}}sort(seg+1,seg+1+tot,greater<int>());int ans=0,sum=0;for(int i=0;i<=min(m,tot);i++){sum+=seg[i];if(f[m-i][cnt]!=-1) ans=max(ans,f[m-i][cnt]+sum);}cout<<ans<<'\n';return 0; }

總結

以上是生活随笔為你收集整理的2021牛客暑期多校训练营2 G.League of Legends(转化+单调队列)的全部內容,希望文章能夠幫你解決所遇到的問題。

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