思路:
2^n次方的暴力总会吧
其实就是折半搜索
c o d e code code
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 40;
int n, a[MAXN], m, ans = 0, d, b[1 << 20], tot;
void dfs(int x, int sum) {
if(x > d) {
b[++ tot] = sum;
return ;
}
dfs(x + 1, (sum + a[x]) % m);
dfs(x + 1, sum);
}
int erfen(int x) {
int l = 1, r = tot, ans = 0;
while(l <= r) {
int mid = l + r >> 1;
if(b[mid] <= x) l = mid + 1, ans = max(b[mid], ans);
else r = mid - 1;
}
return ans;
}
void dfs2(int x, int sum) {
if(x > n) {
if((sum + b[tot]) % m > ans) ans = (sum + b[tot]) % m;
int k = erfen(m - 1 - sum);
if((sum + k) % m > ans) ans = (sum + k) % m;
return ;
}
dfs2(x + 1, (sum + a[x]) % m);
dfs2(x + 1, sum);
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++) scanf("%d", &a[i]), a[i] %= m;
d = n / 2;
dfs(1, 0);
sort(b + 1, b + 1 + tot);
dfs2(d + 1, 0);
printf("%d", ans);
return 0;
}