思路:
把数组分两半分别 dfs,记录前半部分的所有可能和,在后半部分二分,最大值更新答案
直接搜会TLEEEEEEEE
C o d e Code Code:
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int a[50], h[2003220];
int n, m, cnt = 0, ans = 0;
bool cmp(int x,int y)
{
return x > y;//排序
}
void find(int x)//二分查找
{
int l = 1,r = cnt, v;
while (l <= r)
{
int mid = (l + r) >> 1;
if (h[mid] + x <= m)
{
v = h[mid];
l = mid + 1;
}
else
r = mid - 1;
}
ans = max (ans,v + x);//最大值
}
void dfs1(int dep,int sum)
{
if (sum > m)
return;
if (dep > n)
{
h[++cnt] = sum;
return;
}
dfs1(dep + 1,sum + a[dep]);
dfs1(dep + 1,sum);
}
void dfs2(int dep,int sum)
{
if (sum > m)
return;
if (dep > n / 2)
{
find(sum);
return;
}
dfs2(dep + 1, sum + a[dep]);
dfs2(dep + 1, sum);
}
int main()
{
scanf("%d%d",&n,&m);
for (int i = 1;i <= n; i++)
scanf("%d", &a[i]);
sort(a + 1, a + n + 1, cmp);
dfs1(n / 2 + 1, 0);//折半
sort(h + 1, h + cnt + 1);
dfs2(1, 0);
printf("%d\n", ans);
return 0;
}