Educational Codeforces Round 32 E 二分

题意:从数组中选几个(任意),使他们的和modm的值最大

题解:我一开始是直接暴力写,然后就会t

   其实这题可以用二分的方法写,一半数组的值用来遍历,一般数组的值用来查询。

   二分查询就能把时间继续缩短

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=55;
const ll inf=1e9;
set<int> st[2],temp;
int n,m,a[44];
int main(){
    //freopen("in.txt","r",stdin);
    cin >> n >> m;
    for (int i=0;i<n;i++) cin >> a[i];
    
    set<int>::iterator it;
    for(int i=0;i<n/2;i++){
        temp.clear();
        for(it=st[0].begin();it!=st[0].end();it++){
            temp.insert((*it+a[i])%m);
        }
        for(it=temp.begin();it!=temp.end();it++){
            st[0].insert(*it);
        }
        st[0].insert(a[i]%m);
    }
    for(int i=n/2;i<n;i++){
        temp.clear();
        for(it=st[1].begin();it!=st[1].end();it++){
            temp.insert((*it+a[i])%m);
        }
        for(it=temp.begin();it!=temp.end();it++){
            st[1].insert(*it);
        }
        st[1].insert(a[i]%m);
    }
    st[0].insert(0);
    st[1].insert(0);
    
    int ans = 0;
    for (it=st[0].begin();it!=st[0].end();it++){
        //在st[1]中找有无和i配对使值为m-1(或更小) 
        int x = m - *it - 1;
        set<int>::iterator itt = st[1] . upper_bound(x);
        itt--; 
        ans=max(ans,*itt+*it);
    }
    cout << ans << endl;
    return 0;
}
 

猜你喜欢

转载自www.cnblogs.com/amitherblogs/p/12307606.html