2021牛客暑期多校训练营1 G Game of Swapping Numbers 思维 + 巧妙的转换
傳送門
文章目錄
- 題意:
- 思路:
題意:
給你兩個數組A,BA,BA,B,你可以選擇AAA的兩個位置i,j,i<ji,j,i<ji,j,i<j交換Ai,AjA_i,A_jAi?,Aj?,需要交換正好kkk次,問你最大的∑i=1n∣Ai?Bi∣\sum_{i=1}^n|A_i-B_i|∑i=1n?∣Ai??Bi?∣。
思路:
參考題解的轉換方式,我們給A,BA,BA,B數組每個元素分配正負號,只需要使得A,BA,BA,B的正負號總和相等,不必在每個數組中個數相等。
考慮如果最小步數得到最優解,顯然我們給前nnn大的數都標為+++,其他的數都為?-?,讓后再將A,BA,BA,B中的正負號配對即可,這樣步數一定最小。
考慮如何調整到最優解,如果一個位置iii對應A,BA,BA,B的符號不同,那么這一位直接忽略就好。如果有一個位置兩個都是+++,另一個位置兩個都是?-?,那么顯然交換這兩個位置可以更優,增加的值為2?[min(Ai,Bi)?max(Aj,Bj)]2*[min(A_i,B_i)-max(A_j,B_j)]2?[min(Ai?,Bi?)?max(Aj?,Bj?)],當然要保證這兩個區間沒有交集,下面解釋一下沒有交集是什么意思。
我們將[min(Ai,Aj),max(Ai,Aj)][min(A_i,A_j),max(A_i,A_j)][min(Ai?,Aj?),max(Ai?,Aj?)]看成一個區間,將其放在一個數軸上,如下圖:
分配的符號應該是B2,A3,B3B_2,A_3,B_3B2?,A3?,B3?為+++,A1,A2,B1A_1,A_2,B_1A1?,A2?,B1?為?-?,我們在中間畫一個線將兩邊隔開,如果現在k>=1k>=1k>=1的話,我們可以交換A1,A3A_1,A_3A1?,A3?,可以發現增加2?(A3?B1)2*(A_3-B_1)2?(A3??B1?),這也就是我們上面說的2?[min(Ai,Bi)?max(Aj,Bj)]2*[min(A_i,B_i)-max(A_j,B_j)]2?[min(Ai?,Bi?)?max(Aj?,Bj?)],并且可以發現除去跨過中間線的區間,不跨過中間線的區間,在線兩邊的數量一定相等,所以我們按照min(Ai,Bi)min(A_i,B_i)min(Ai?,Bi?)從大到小排序,max(Ai,Bi)max(A_i,B_i)max(Ai?,Bi?)從小到大排序,之后取前kkk個位置即可,注意要判斷一下是否相交。
給出一個結論:在n>2n>2n>2的情況下,由鵲巢原理得AAA中的符號至少有兩個+++或?-?,所以多出來的操作通過交換這兩個即可消除,可以轉換成至多kkk次操作。
最后注意特判一下n=2n=2n=2的情況即可。
// Problem: Game of Swapping Numbers // Contest: NowCoder // URL: https://ac.nowcoder.com/acm/contest/11166/G // Memory Limit: 524288 MB // Time Limit: 2000 ms // // Powered by CP Editor (https://cpeditor.org)//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native") //#pragma GCC optimize(2) #include<cstdio> #include<iostream> #include<string> #include<cstring> #include<map> #include<cmath> #include<cctype> #include<vector> #include<set> #include<queue> #include<algorithm> #include<sstream> #include<ctime> #include<cstdlib> #include<random> #include<cassert> #define X first #define Y second #define L (u<<1) #define R (u<<1|1) #define pb push_back #define mk make_pair #define Mid ((tr[u].l+tr[u].r)>>1) #define Len(u) (tr[u].r-tr[u].l+1) #define random(a,b) ((a)+rand()%((b)-(a)+1)) #define db puts("---") using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); } //void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); } //void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII;const int N=2000010,mod=1e9+7,INF=0x3f3f3f3f; const double eps=1e-6;int n,k; int a[N],b[N]; int l[N],r[N];bool cmp(int a,int b) {return a>b; }int main() { // ios::sync_with_stdio(false); // cin.tie(0);scanf("%d%d",&n,&k);for(int i=1;i<=n;i++) scanf("%d",&a[i]);for(int i=1;i<=n;i++) scanf("%d",&b[i]); if(n==2) {if(k%2==1) swap(a[1],a[2]);printf("%d\n",abs(a[1]-b[1])+abs(a[2]-b[2]));} else {LL ans=0;for(int i=1;i<=n;i++) ans+=abs(a[i]-b[i]),l[i]=min(a[i],b[i]),r[i]=max(a[i],b[i]);sort(r+1,r+1+n); sort(l+1,l+1+n,cmp);for(int i=1;i<=min(n,k);i++) if(r[i]<l[i]) ans+=2*(l[i]-r[i]); else break;printf("%lld\n",ans);}return 0; } /**/ 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的2021牛客暑期多校训练营1 G Game of Swapping Numbers 思维 + 巧妙的转换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何将amr格式转换为mp3格式amr改
- 下一篇: 2021牛客暑期多校训练营1 H Has