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"
#include "string"
#include "vector"
#include "set"
#include "map"
#include "algorithm"
#include "stdio.h"
#include "math.h"
#pragma comment(linker, "/STACK:102400000,102400000")
#define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
#define mem(a,x) memset(a,x,sizeof(a))
#define step(x) fixed<< setprecision(x)<<
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define ll long long
#define endl ("\n")
#define ft first
#define sd second
#define lrt (rt<<1)
#define rrt (rt<<1|1)
using namespace std;
const ll mod=1e9+7;
const ll INF = 1e18+1LL;
const int inf = 1e9+1e8;
const double PI=acos(-1.0);
const int N=1e5+100;

int a[N],ans;
vector<int> vex1, vex2;
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; ++i){
        scanf("%d",&a[i]);
        a[i]%=m;
    }
    int p=n>>1, q=n-p;
    for(int i=0; i<(1<<p); ++i){
        int u=0;
        for(int j=0; j<p; ++j){
            if(i&(1<<j)) u=(u+a[j+1])%m;
        }
        vex1.pb(u%m);
    }
    for(int i=0; i<(1<<q); ++i){
        int u=0;
        for(int j=0; j<q; ++j){
            if(i&(1<<j)) u=(u+a[j+p+1])%m;
        }
        vex2.pb(u%m);
    }
    sort(vex1.begin(), vex1.end()), unique(vex1.begin(), vex1.end());
    sort(vex2.begin(), vex2.end()), unique(vex2.begin(), vex2.end());
    for(auto u : vex1){
        int g=m-u;
        int it = lower_bound(vex2.begin(),vex2.end(),g) - vex2.begin()-1;
        if(it<0) continue;
        ans=max(ans, u+vex2[it]);
    }
    printf("%d\n",ans);
    return 0;
}
时间: 2024-08-28 09:35:53

Educational Codeforces Round 32 E 巨型背包的相关文章

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. 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; +

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 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 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时,用单调栈维护.具体看代码,模拟一下就知道了. 然后把所有的贡献加起来.

Educational Codeforces Round 25 F. String Compression(kmp+dp)

题目链接:Educational Codeforces Round 25 F. String Compression 题意: 给你一个字符串,让你压缩,问压缩后最小的长度是多少. 压缩的形式为x(...)x(...)  x表示(...)这个出现的次数. 题解: 考虑dp[i]表示前i个字符压缩后的最小长度. 转移方程解释看代码,这里要用到kmp来找最小的循环节. 当然还有一种找循环节的方式就是预处理lcp,然后通过枚举循环节的方式. 这里我用的kmp找的循环节.复杂度严格n2. 1 #inclu

Educational Codeforces Round 23 E. Choosing The Commander (trie)

题目链接: Educational Codeforces Round 23 E. Choosing The Commander 题意: 一共有n个操作. 1.  插入一个数p 2.  删除一个数p 3.  询问有多少个数 使得 x^p<l 题解: 对于前两种操作用01trie就能解决. 对于对三个操作,我们考虑在trie上搜索. 1.  当l的bit位是1时,那边bit位是p的字数全部的数都会小于l,(因为p^p=0) 2.  当l的bit为是0时,那边只能向bit位是p的子树中搜. 这样算下来