文章目录
- 送礼物
一、送礼物OJ链接
本题思路:
#include <bits/stdc++.h>
typedef long long LL;
constexpr int N=1<<25;
int n,m,k;
int g[50];
int weight[N],cnt;
int ans;
void dfs1(int u,int s)
{
if(u==k){
weight[cnt++]=s;
return;
}
dfs1(u+1,s);
if(g[u]+(LL)s<=m) dfs1(u+1,s+g[u]);
}
void dfs2(int u,int s)
{
if(u==n){
int l=0,r=cnt-1;
while(l<r){
int mid=l+r+1>>1;
if(weight[mid]<=m-s) l=mid;
else r=mid-1;
}
ans=std::max(ans,weight[l]+s);
return;
}
dfs2(u+1,s);
// 选择当前这个物品
if ((LL)s + g[u] <= m)
dfs2(u + 1, s + g[u]);
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);std::cout.tie(nullptr);
std::cin>>m>>n;
for(int i=0;i<n;i++) std::cin>>g[i];
//优先从大到小进行排序
std::sort(g,g+n,std::less<int>());
k=n>>1;//将前k个物品进行打表处理
dfs1(0,0);
// 做完之后, 把weights数组从小到大排序
std::sort(weight, weight + cnt);
// 判重
cnt=std::unique(weight,weight+cnt)-weight;
// 从k开始, 当前的和是0
dfs2(k, 0);
std::cout<<ans<<std::endl;
return 0;
}