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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Gym - 101471D Money for Nothing(决策单调性+分治+贪心)

發布時間:2024/4/11 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Gym - 101471D Money for Nothing(决策单调性+分治+贪心) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:在二維平面中給出 n 個點可以作為矩形左下角的點,再給出 m 個點可以作為矩形右上角的點,現在問最大可以構造出多大面積的矩形,即如何選擇,可以使得 ( b[ j ] . x?- a[ i ] . x ) * ( b[ j ] . y - a[ i ] . y ) 最大

題目分析:首先貪心去想,對于矩形左下角的點來說,如果存在著兩個點 A( x1 , y1 ),B( x2 , y2 ),滿足 x1 < y1 且 x2 < y2 的話,那么點 A 一定是要比點 B 永遠都是更優的,所以可以直接把點 B 刪除掉,對于矩形右上角的點也是同理,這個操作在預處理時線性遍歷一遍就可以完成,貪心完成后剩余的點應該如下圖所示:

如果用圖示畫出來的話,應該往斜率優化dp或者決策單調性方面去想,因為是二維的點,斜率優化的話需要三維凸包,所以考慮決策單調性

簡單來說就是,設數組 a 是左下角的點,數組 b 是右下角的點,如果 a[ i ] 和 b[ j ] 是最優的,也就是 a[ i ] 和 b[ j - 1 ] 不是最優的,那么 a[ i + 1 ] 一定不可能和 b[ j - 1 ] 是最優的,證明如下:

所以不難看出,最后的化簡的公式與假設相悖,所以得證

如此一來就可以分治去解決了,具體策略如下:設 solve( l1 , r1 , l2 , r2 ) 為當前區間的詢問區間為 [ l1 , r1 ] ,決策所在區間為 [ l2 , r2 ] 時的最優答案,即 [ l1 , r1 ] 對應的是數組 a,[ l2 , r2 ] 對應的是數組 b,每次選擇詢問區間的中位數去決策區間中尋找最優決策設為 pos,根據決策單調性不難看出,[ l1 , mid - 1 ] 的決策只可能在 [ l1 , pos ] 中出現,同理 [ mid + 1 , r1 ] 的決策只可能在 [ pos , r2 ] 中出現,如此遞歸下去時間復雜度是 O( nlogn ) 級別的

有一點小細節就是,有可能決策為負數,或者 a 變成了矩陣的右上角端點,b 變成了矩陣的左下角端點,此時的決策應該是負無窮(不應該出現這種情況),雖然決策為負數時無法更新答案,但是卻可以更新相對的最優情況,如此分治下去肯定是最優的

代碼:
?

//#pragma GCC optimize(2) //#pragma GCC optimize("Ofast","inline","-ffast-math") //#pragma GCC target("avx,sse2,sse3,sse4,mmx") #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> using namespace std;typedef long long LL;typedef unsigned long long ull;const LL inf=0x3f3f3f3f3f3f3f3f;const int N=1e6+100;int n,m;bool ban[N];struct Node {LL x,y;void input(){scanf("%lld%lld",&x,&y);}bool operator<(const Node& t)const{if(x!=t.x)return x<t.x;return y<t.y;} }a[N],b[N];void init_a() {sort(a+1,a+1+n);memset(ban,false,sizeof(ban));int last=1;for(int i=2;i<=n;i++){if(a[i].y>=a[last].y)ban[i]=true;elselast=i;}int tot=0;for(int i=1;i<=n;i++)if(!ban[i])a[++tot]=a[i];n=tot; }void init_b() {sort(b+1,b+1+m);memset(ban,false,sizeof(ban));int last=m;for(int i=m-1;i>=1;i--){if(b[i].y<=b[last].y)ban[i]=true;elselast=i;}int tot=0;for(int i=1;i<=m;i++)if(!ban[i])b[++tot]=b[i];m=tot; }LL cal(int i,int j) {if(b[j].x<a[i].x&&b[j].y<a[i].y)return -inf;return (b[j].x-a[i].x)*(b[j].y-a[i].y); }LL solve(int l1,int r1,int l2,int r2)//a[l1,r1],b[l2,r2] {if(l1>r1||l2>r2)return 0;int mid=l1+r1>>1;int pos=l2;for(int i=l2+1;i<=r2;i++)if(cal(mid,pos)<cal(mid,i))pos=i;return max({solve(l1,mid-1,l2,pos),solve(mid+1,r1,pos,r2),cal(mid,pos)}); }int main() { #ifndef ONLINE_JUDGE // freopen("data.ans.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)a[i].input();for(int i=1;i<=m;i++)b[i].input();init_a();init_b();printf("%lld\n",solve(1,n,1,m));return 0; }

?

總結

以上是生活随笔為你收集整理的Gym - 101471D Money for Nothing(决策单调性+分治+贪心)的全部內容,希望文章能夠幫你解決所遇到的問題。

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