E. Maximum Subsequence
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given an array a consisting of n integers, and additionally an integer m. You have to choose some sequence of indicesb1, 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
思路:折半枚举大法好,因为数组最长为35,所以分别对数组前半和后半的和对m取模的情况进行枚举,然后对一个排序后二分搜索模m最大值,复杂度为2^(n/2)logn。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
int a[40];
int data1[300005];
int data2[300005];
int cnt1;
int cnt2;
int n,m;
void dfs1(int sum,int i,int n)
{
if(i>(n-1)/2)
{
data1[cnt1++]=sum;
return;
}
dfs1((sum+a[i])%m,i+1,n);
dfs1(sum%m,i+1,n);
}
void dfs2(int sum,int i,int n)
{
if(i>=n)
{
data2[cnt2++]=sum;
return;
}
dfs2((sum+a[i])%m,i+1,n);
dfs2(sum%m,i+1,n);
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
cnt1=0;
cnt2=0;
dfs1(0,0,n);
dfs2(0,(n-1)/2+1,n);
sort(data2,data2+cnt2);
int ans=0;
for(int i=0;i<cnt1;i++)
{
int x = m-data1[i];
int p1=lower_bound(data2,data2+cnt2,x)-data2;
if(p1>0)
{
ans=max(ans,(data1[i]+data2[p1-1])%m);
}
ans=max(ans,(data1[i]+data2[cnt2-1])%m);
}
printf("%d\n",ans);
}
}