Educational Codeforces Round 32 Maximum Subsequence CodeForces - 888E (meet-in-the-middle,二分,枚举)
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), '\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';
}
}
}
Educational Codeforces Round 32 Maximum Subsequence CodeForces - 888E (meet-in-the-middle,二分,枚举)的更多相关文章
- Codeforces Beta Round #32 (Div. 2, Codeforces format)
Codeforces Beta Round #32 (Div. 2, Codeforces format) http://codeforces.com/contest/32 A #include< ...
- Educational Codeforces Round 32:E. Maximum Subsequence(Meet-in-the-middle)
题目链接:E. Maximum Subsequence 用了一个Meet-in-the-middle的技巧,还是第一次用到这个技巧,其实这个技巧和二分很像,主要是在dfs中,如果数量减小一半可以节约很 ...
- Educational Codeforces Round 32
http://codeforces.com/contest/888 A Local Extrema[水] [题意]:计算极值点个数 [分析]:除了第一个最后一个外,遇到极值点ans++,包括极大和极小 ...
- Codeforces Round #524 (Div. 2) codeforces 1080A~1080F
目录 codeforces1080A codeforces 1080B codeforces 1080C codeforces 1080D codeforces 1080E codeforces 10 ...
- Educational Codeforces Round 32 E. Maximum Subsequence
题目链接 题意:给你两个数n,m,和一个大小为n的数组. 让你在数组找一些数使得这些数的和模m最大. 解法:考虑 dfs但是,数据范围不允许纯暴力,那考虑一下折半搜索,一个从头开始往中间搜,一个从后往 ...
- Educational Codeforces Round 32 Problem 888C - K-Dominant Character
1) Link to the problem: http://codeforces.com/contest/888/problem/C 2) Description: You are given a ...
- Educational Codeforces Round 32 Almost Identity Permutations CodeForces - 888D (组合数学)
A permutation p of size n is an array such that every integer from 1 to n occurs exactly once in thi ...
- Educational Codeforces Round 32 E 二分
题意:从数组中选几个(任意),使他们的和modm的值最大 题解:我一开始是直接暴力写,然后就会t 其实这题可以用二分的方法写,一半数组的值用来遍历,一般数组的值用来查询. 二分查询就能把时间继续缩短 ...
- Educational Codeforces Round 21 Problem E(Codeforces 808E) - 动态规划 - 贪心
After several latest reforms many tourists are planning to visit Berland, and Berland people underst ...
随机推荐
- spring boot官方配置
#BANNER banner.charset = UTF-8 #横幅文件编码.banner.location = classpath:banner.txt #横幅文件位置.banner.image.l ...
- 十九、RF接口测试汇总(一)
搭建项目:转自 http://chuansong.me/n/1858477 A.请求方式为get请求 方式一:导入RequestsLibrary库,get request [ alias | ...
- udp组播的实现
组播在内核里面对应的一个重要的结构体是ip_mreq,如下: struct ip_mreq { struct in_addr imr_multiaddr; /* IP multicast addres ...
- fiddler之简单的接口性能测试(replay)
在针对某一个/某一些接口,发送相同的请求,不考虑参数的变化时,可以使用fiddler进行简单的性能测试.(使用功能为:replay) 一.replay功能调用 (1.Reissue Requests: ...
- python学习之文件读写操作
open函数 在使用文件之前,需要先打开,即使用open函数 如: files=open("文件路径","操作方式") 解释如下: (1.files:为文件对象 ...
- Selenium学习之==>Xpath使用方法
一.什么是Xpath XPath是XML的路径语言,通俗一点讲就是通过元素的路径来查找到这个标签元素. 工具 Xpath的练习建议大家安装火狐浏览器后,下载插件,FireBug.由于最新版火狐不再支持 ...
- 【Qt开发】解决Qt程序在Linux下无法输入中文的办法
解决Qt程序在Linux下无法输入中文的办法 一位网友问我如何在Linux的Qt的应用程序中输入中文,我一开始觉得不是什么问题,但是后面自己尝试了一下还真不行.不仅是Qt制作的应用程序,就连Qt Cr ...
- editText内容从hint右输入
如何让editText内容从hint右输入呢: <EditText android:id="@+id/et_password" android:textColor=" ...
- HTTP请求状态码为400时的原因
2019-11-30 出现这个请求无效说明请求没有进入后台服务器里 原因: (1)前端提交的字段名称或者字段类型和后台的实体类不一样 或者前端提交的参数跟后台需要的参数个数不一致,导致无法封装 (2) ...
- java基础笔记(4)
二进制运算: &的应用:清零.得到指定位的数: |的应用:将指定位置取1: ^的应用:取反.保留原值:交换两个bian变量:A= A^B,B =A ^ B,A = A^B;(原理就是本身异或本 ...