教育Codeforcesラウンド32の最大サブシーケンスCodeForces - 888E(ミート・イン・ザ・ミドル、二分、枚举)

もしnは整数からなる配列、およびさらに整数mが与えられます。あなたは、インデックスのB1、B2、...、BKのいくつかの列を選択する必要があります(1≤B1 <B2 <... <BK≤n)の値が最大になるような方法インチ 選択された配列は空にすることができます。

の可能な最大値を出力します。

入力は、
最初の行は二つの整数nとm(35≤1≤N、109≤1≤M)を含みます。

2行目は、n個の整数のA1、A2、...、(1≤AI≤109)を含みます。

出力が
可能な最大値を出力します。


入力
4 4
5 2 4 1
出力
3
入力
3 20
199 41 299
出力
19

最初の例では、シーケンスB = {1,2}を選択することができるので、合計は7に等しくなる(かつ、それを取った後、3'Sモジュロ4)。

第二の例では、シーケンスb = {3}を選択することができます。

質問の意味:
数とモジュロmの最大値のサブセット和ようにあなたの配列aを与え、数mにする、あなたは、配列のサブセットを選択することができます。
アイデア:
すべての子の最初の部分、最大の数の各部分が各セクションのために、35/2の大きさで、我々はすべてのバイナリ状態を列挙し、イン・ミドル・アイデアで会う、配列は2つの部分に分かれて和(モジュロ同意)を得、次いで、同じ操作の第2の部分は、モジュロ和は、アレイは第一の部分のX各番号に、最終的にV1とV2とに加え、第二の部分は、設定しますできるだけ大きく(x + y)のように%のM、数yを見つけます。
次いで、X + Yは、2例に分割されている
ときにX + Y以上M、
その結果は、x + YM値が大きくなるように、我々は、最大値を選択したい場合、Y。
逆にX + Y <Mのある
最大値よりも小さい場合はx + yはM-1に近くなるように、YのMX

詳細コードを参照してください。

#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), '\0', 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 == '\n');
    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/p/11098151.html