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

    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 a1, a2, ..., an (1 ≤ ai ≤ 109).

    Output
    Print the maximum possible value of .

    Examples
    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}.

    题意:
    给你一个数组a,和一个数m,让你选出一个数组a的子集,让子集中的数的sum和对m取模后的数值最大。
    思路:
    meet-in-the-middle 的思路,把数组分成两个部分,每一个部分数最多就是 35/2 的大小,对于每一个部分,我们通过二进制枚举所有状态, 把第一部分的所有子集的sum和求出(同意取模),然后第二部分同样的操作,把取模后的sum分别加入到数组v1和v2中,最后对于第一部分的每一个数x,去第二部分中找一个数y,使之(x+y )%m 尽量大。
    那么x+y 分为两种情况,
    当x+y 大于等于m,
    那么结果是 x+y-m 的,那么这里的y我们不妨选择最大的,这样可以使数值更大。
    反之就是 x+y<m
    y要是小于m-x 中的最大值,这样x+y 更接近m-1

    细节见代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define rt return
    #define sz(a) int(a.size())
    #define all(a) a.begin(), a.end()
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
    using namespace std;
    typedef long long ll;
    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;}
    inline void getInt(int* p);
    const int maxn=1000010;
    const int inf=0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    ll a[60];
    std::vector<ll> v1;
    std::vector<ll> v2;
    ll haf;
    ll n,m;
    void dfs1(int id,ll num)
    {
    	v1.pb(num%m);
    	if(id<=haf)
    	{
    		dfs1(id+1,num);
    		dfs1(id+1,num+a[id]);
    	}
    }
    void dfs2(int id,ll num)
    {
    	v2.pb(num%m);
    	if(id<=n)
    	{
    		dfs2(id+1,num);
    		dfs2(id+1,num+a[id]);
    	}
    }
    int main()
    {
        // freopen("D:\code\text\input.txt","r",stdin);
    	//freopen("D:\code\text\output.txt","w",stdout);
    	gbtb;
    	cin>>n>>m;
    	repd(i,1,n)
    	{
    		cin>>a[i];
    		a[i]%=m;
    	}
    	haf=(n>>1);
    	dfs1(1,0ll);
    	dfs2(haf+1,0ll);
    	sort(ALL(v1));
    	sort(ALL(v2));
    	v1.erase(unique(ALL(v1)),v1.end());
    	v2.erase(unique(ALL(v2)),v2.end());
    	ll ans=0ll;
    	int p=sz(v2);
    	int q=sz(v1);
    	for(auto x:v1)
    	{
    		int pos=lower_bound(ALL(v2),m-x)-v2.begin();
    		if(pos>=1&&pos<p)
    		{
    			ans=max(ans,(x+v2[pos-1])%m);
    		}
    		ans=max(ans,(x+v2[p-1])%m);
    	}
    	cout<<ans<<endl;
        return 0;
    }
    
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
    
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    JAVA日报
    JAVA日报
    论文爬取(七)
    论文爬取(六)
    论文爬取(五)
    JAVA日报
    JAVA日报
    剑指 Offer 68
    剑指 Offer 68
    剑指 Offer 67. 把字符串转换成整数
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/11098151.html
Copyright © 2011-2022 走看看