zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 32 E. Maximum Subsequence

    题目链接
    题意:给你两个数n,m,和一个大小为n的数组。
    让你在数组找一些数使得这些数的和模m最大。
    解法:考虑 dfs但是,数据范围不允许纯暴力,那考虑一下折半搜索,一个从头开始往中间搜,一个从后往中间搜。在中间相遇的时间二分更新最大值即可。

    #include<bits/stdc++.h>
    
    #define LL long long
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    
    using namespace std;
    
    LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
    LL lcm(LL a,LL b){return a/gcd(a,b)*b;}
    LL powmod(LL a,LL b,LL MOD){LL ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
    int n,m,cnt;
    int a[37],b[37];
    int ans;
    int sum1[(1<<20)];
    vector<int>v;
    int main(){
    	ios::sync_with_stdio(false);
    	cin>>n>>m;
    	for(int i=0;i<n;i++)cin>>a[i],a[i]%=m,ans=max(ans,a[i]);
    	for(int i=0;i<(1<<(n/2));i++){
    		for(int j=0;j<n/2;j++)if(i&(1<<j))sum1[i]=(0ll+sum1[i]+a[j])%m;	
    		ans=max(ans,sum1[i]);
    		v.pb(sum1[i]);
    	}
    	sort(v.begin(),v.end());
    	for(int i=n/2;i<n;i++)b[cnt++]=a[i];
    	for(int i=0;i<(1<<cnt);i++){
    		int A=0;
    		for(int j=0;j<cnt;j++)if((1<<j)&i)A=(0ll+A+b[j])%m;
    		ans=max(ans,A);
    		auto pos=upper_bound(v.begin(), v.end(),m-A-1);
    		pos--;
    		ans=max(1ll*ans,(0ll+A+(*pos))%m);
    	}
    	cout<<ans%m;
    	return 0;	
    }
    
    
  • 相关阅读:
    主席树模板之区间问题
    简易版第k大(权值线段树+动态开点模板)
    Irrigation
    Petya and Array
    H. Pavel's Party(权值线段树)
    权值线段树入门
    位数差(二分)
    ZYB's Premutation(树状数组+二分)
    单调队列入门
    javaBean为什么要implements Serializable?
  • 原文地址:https://www.cnblogs.com/pubgoso/p/10759711.html
Copyright © 2011-2022 走看看