AtCoder AGC032E Modulo Pairing (二分、贪心与结论)
生活随笔
收集整理的這篇文章主要介紹了
AtCoder AGC032E Modulo Pairing (二分、贪心与结论)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接
https://atcoder.jp/contests/agc032/tasks/agc032_e
題解
猜結論好題。
結論是: 按\(a_i\)從小到大排序之后,一定存在一種最優解,使得以某個位置為界,兩邊分別首尾匹配,且滿足左邊的每一對的和都\(<M\), 右邊每一對的和都\(\ge M\).
證明不難,可參考官方題解,此處不再贅述。
然后顯然可以枚舉這個臨界點,然后\(O(n)\)暴力計算答案,時間復雜度\(O(n^2)\).
考慮優化: 在我們配對的時候,當臨界點右移,左右兩側的每一對和都會變大。
于是我們只需找到最小的合法臨界點,即是最優解。
二分找即可,時間復雜度\(O(n\log n)\).
代碼
#include<cstdio> #include<cstdlib> #include<iostream> #include<cassert> #include<algorithm> using namespace std;const int N = 2e5; int a[N+3]; int n,m;int main() {scanf("%d%d",&n,&m);for(int i=1; i<=n+n; i++) scanf("%d",&a[i]);sort(a+1,a+n+n+1);int left = 0,right = n;while(left<right){int mid = left+((right-left)>>1);bool ok = true;for(int i=mid*2+1; i<=n+n; i++){if(a[i]+a[n+n+mid+mid+1-i]<m) {ok = false; break;}}if(ok==true) {right = mid;}else {left = mid+1;}}int pos = 2*right;int ans = 0;for(int i=1; i<=pos; i++) ans = max(ans,a[i]+a[pos+1-i]);for(int i=pos+1; i<=n+n; i++) ans = max(ans,(a[i]+a[n+n+pos+1-i])-m);printf("%d\n",ans);return 0; }總結
以上是生活随笔為你收集整理的AtCoder AGC032E Modulo Pairing (二分、贪心与结论)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AtCoder AGC038F Two
- 下一篇: AtCoder AGC032E Modu