Educational Codeforces Round 32 E. Maximum Subsequence

E. Maximum Subsequence

题意: n 个数,选出其中  k 个数,使得他们的和对 m 取模后最大。 输出这个最大值。

tags:注意到 n 很小, 所以折半枚举。

//  E
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a; i<=b; ++i)
#define per(i,b,a) for (int i=b; i>=a; --i)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 800005;

ll  n, m, s1[N], s2[N], a[N];
int main()
{
    scanf("%lld%lld", &n, &m);
    rep(i,1,n) scanf("%lld", &a[i]);
    int n1 = n/2, n2 = n-n1;
    int cnt1 = (1<<n1)-1, cnt2 = (1<<n2)-1;
    for(int i=0; i<=cnt1; ++i)
    {
        ll num = 0;
        for(int j=0; j<n1; ++j)
            if((i>>j)&1) num += a[j+1];
        s1[i] = num%m;

    }
    for(int i=0; i<=cnt2; ++i)
    {
        ll num = 0;
        for(int j=0; j<n2; ++j)
            if((i>>j)&1) num += a[n1+j+1];
        s2[i] = num%m;
    }
    sort(s2, s2+cnt2+1);
    sort(s1, s1+cnt1+1);
    cnt1 = unique(s1, s1+cnt1+1) - s1;
    cnt2 = unique(s2, s2+cnt2+1) - s2;
    --cnt1, --cnt2;
    ll  ans = 0;
    for(int i=0; i<=cnt1; ++i)
    {
        ll num = m-s1[i];
        int pos = lower_bound(s2, s2+cnt2+1, num) - s2;
        if(pos==cnt2+1 || pos>0)
            ans = max(ans, s1[i]+s2[pos-1]);
    }
    printf("%lld\n", ans);

    return 0;
}

原文地址:https://www.cnblogs.com/sbfhy/p/7814640.html

时间: 2024-10-08 18:45:34

Educational Codeforces Round 32 E. Maximum Subsequence的相关文章

Educational Codeforces Round 32

Educational Codeforces Round 32 A. Local Extrema 直接模拟一下- B. Buggy Robot x和y轴无关,分别考虑即可 C. K-Dominant Character 想到了做法,但是没过... 就是记录一下相同字母的最大间距,然后取最小的即可- 不过要注意首尾的处理,WA了好多发都没注意到这个问题=_=|| D. Almost Identity Permutations k很小,直接组合数+错排搞一下就好了

Educational Codeforces Round 32 E

E. Maximum Subsequence 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

Educational Codeforces Round 32 E 巨型背包

思路:n只有35, 将n份为2部分,一部分为前n/2个物品的取舍(取或不去), 另一部分为剩下物品的取舍,复杂度为2^(n/2),枚举左边的数,然后二分右边的数找到最优解,写lower_bound需要去重,手写二分就不需要了 AC代码: #include "iostream" #include "iomanip" #include "string.h" #include "stack" #include "queue

Educational Codeforces Round 36 (Rated for Div. 2)

Educational Codeforces Round 36 (Rated for Div. 2) F. Imbalance Value of a Tree You are given a tree T consisting of n vertices. A number is written on each vertex; the number written on vertex i is ai. Let's denote the function I(x,?y) as the differ

Educational Codeforces Round 71 (Rated for Div. 2) A - There Are Two Types Of Burgers

原文链接:https://www.cnblogs.com/xwl3109377858/p/11404050.html Educational Codeforces Round 71 (Rated for Div. 2) A - There Are Two Types Of Burgers There are two types of burgers in your restaurant — hamburgers and chicken burgers! To assemble a hamburg

Educational Codeforces Round 21 G. Anthem of Berland(dp+kmp)

题目链接:Educational Codeforces Round 21 G. Anthem of Berland 题意: 给你两个字符串,第一个字符串包含问号,问号可以变成任意字符串. 问你第一个字符串最多包含多少个第二个字符串. 题解: 考虑dp[i][j],表示当前考虑到第一个串的第i位,已经匹配到第二个字符串的第j位. 这样的话复杂度为26*n*m*O(fail). fail可以用kmp进行预处理,将26个字母全部处理出来,这样复杂度就变成了26*n*m. 状态转移看代码(就是一个kmp

Educational Codeforces Round 26 D. Round Subset(dp)

题目链接:Educational Codeforces Round 26 D. Round Subset 题意: 给你n个数,让你选其中的k个数,使得这k个数的乘积的末尾的0的个数最大. 题解: 显然,末尾乘积0的个数和因子2和因子5的个数有关. 然后考虑dp[i][j]表示选i个数,当前因子5的个数为j时,能得到因子2最多的为多少. 那么对于每个数,记录一下因子2和5的个数,做一些01背包就行了. 1 #include<bits/stdc++.h> 2 #define mst(a,b) me

Educational Codeforces Round 23 F. MEX Queries(线段树)

题目链接:Educational Codeforces Round 23 F. MEX Queries 题意: 一共有n个操作. 1.  将[l,r]区间的数标记为1. 2.  将[l,r]区间的数标记为0. 3.  将[l,r]区间取反. 对每个操作,输出标记为0的最小正整数. 题解: hash后,用线段树xjb标记一下就行了. 1 #include<bits/stdc++.h> 2 #define ls l,m,rt<<1 3 #define rs m+1,r,rt<&l

Educational Codeforces Round 23 D. Imbalanced Array(单调栈)

题目链接:Educational Codeforces Round 23 D. Imbalanced Array 题意: 给你n个数,定义一个区间的不平衡因子为该区间最大值-最小值. 然后问你这n个数所有的区间的不平衡因子和 题解: 对每一个数算贡献,a[i]的贡献为 当a[i]为最大值时的 a[i]*(i-l+1)*(r-i+1) - 当a[i]为最小值时的a[i]*(i-l+1)*(r-i+1). 计算a[i]的l和r时,用单调栈维护.具体看代码,模拟一下就知道了. 然后把所有的贡献加起来.