• Codeforces 888E Maximum Subsequence


    Discription

    You are given an array a consisting of n integers, and additionally an integer m. You have to choose some sequence of indices b1, b2, ..., bk (1 ≤ b1 < b2 < ... < bk ≤ n) in such a way that the value of  is maximized. Chosen sequence can be empty.

    Print the maximum possible value of .

    Input

    The first line contains two integers n and m (1 ≤ n ≤ 35, 1 ≤ m ≤ 109).

    The second line contains n integers a1a2, ..., an (1 ≤ ai ≤ 109).

    Output

    Print the maximum possible value of .

    Example

    Input
    4 4
    5 2 4 1
    Output
    3
    Input
    3 20
    199 41 299
    Output
    19

    Note

    In the first example you can choose a sequence b = {1, 2}, so the sum  is equal to 7 (and that's 3 after taking it modulo 4).

    In the second example you can choose a sequence b = {3}.

    (感觉看到n<=35的第一反应已经是折半搜索了hhh)

    显然可以先搜出前n/2个数和后面剩的数可以得到的所有子集(包括空集)的结果(对m取模后)。

    然后答案肯定就是从前面选一个子集,后面再选一个子集,把两个拼起来。

    假设我们在前n/2中选的子集的权值是s,那么怎么在后面的数中找最优子集呢?

    假设我们在后面的数中找的子集的权值是p,那么有两种情况:

    1.s+p<m

    2.m<=s+p<2*m

    对于第一种情况,我们找到<m-s的最大的p即可;

    对于第二种情况,我们找到最大的p即可(肯定得减掉一个m,所以p肯定是越大越好)

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #define ll long long
    #define maxn 500005
    using namespace std;
    int a[maxn],n,m,b[maxn];
    int num[105],tot,haf,ha;
    int ans=0;
    
    void dfs1(int x,int sum){
        if(sum>=ha) sum-=ha;
        if(x==haf){
            a[++n]=sum;
            return;
        }
        dfs1(x+1,sum);
        dfs1(x+1,sum+num[x+1]);
    }
    
    void dfs2(int x,int sum){
        if(sum>=ha) sum-=ha;
        if(x==tot){
            b[++m]=sum;
            return;
        }
        dfs2(x+1,sum);
        dfs2(x+1,sum+num[x+1]);
    }
    
    int main(){
        scanf("%d%d",&tot,&ha);
        for(int i=1;i<=tot;i++){
            scanf("%d",num+i);
            if(num[i]>=ha) num[i]-=num[i]/ha*ha;
        }
        haf=tot>>1;
        
        dfs1(0,0);
        dfs2(haf,0); 
        
        sort(a+1,a+n+1);
        sort(b+1,b+m+1);
        
        for(int i=1;i<=n;i++){
            int pos=lower_bound(b+1,b+m+1,ha-a[i])-b;
            ans=max(ans,a[i]+b[pos-1]);
            ans=max(ans,a[i]+b[m]-ha);
        }
        
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    简单的java socket 示例
    Java Socket编程
    session的常用方法。
    Request与session与application的区别
    百度echart使用心得,百度图表。
    SpingMVC ModelAndView, Model,Control以及参数传递
    Flume理论研究与实验
    RocketMq在SparkStreaming中的应用总结
    数据实践过程中理论总结
    flink-vs.-spark
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8327737.html
Copyright © 2020-2023  润新知