Educational Codeforces Round 32E. Maximum Subsequence(meet-in-the-middle)

E. Maximum Subsequence

题意:

第一行输入 n ( 35 ) , m ( 1 e 9 ) n(35),m(1e9) n(35),m(1e9);
第二行 a 1 , a 2 , … , a n ( 1 e 9 ) a_1,a_2,\dots,a_n(1e9) a1,a2,,an(1e9)
问:在数组中选择几个数使 ∑ a i m o d    m \sum a_i\mod m aimodm最大。

题解:

首先想到的是直接暴力搜索,这样复杂度是 O ( 2 n ) O(2^n) O(2n),显然是超时的。
这里用到一种叫meet-in-the-middle的搜索优化。
1、将 n n n分为两部分 n / 2 n/2 n/2
2、对这两部分分别进行搜索,并把搜索的结果分别插入 s e t set set中;
3、最后循环第一部分,二分找第二部分中使答案最大的值。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,m,a[40];
vector<int>b[2];
set<int>c[2];
void dfs(vector<int>a,int x,int y,set<int> &b){
    if(x==a.size()){
        b.insert(y);
        return;
    }
    dfs(a,x+1,y,b);
    dfs(a,x+1,(y+a[x])%m,b);
}
int mx;
int main(){
    //freopen("tt.in","r",stdin),freopen("tt.out","w",stdout);
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>a[i],b[i>=n/2].push_back(a[i]);
    dfs(b[0],0,0,c[0]);dfs(b[1],0,0,c[1]);
    for(auto i:c[0])mx=max(mx,i+*(--c[1].upper_bound(m-1-i)));
    cout<<mx<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值