AcWing 171. 送礼物(reverse-unique)
原题链接
简单
作者:
宇小苏
,
2020-04-19 21:36:16
,
所有人可见
,
阅读 750
import java.util.*;
class Main{
private static int n, m, k, cnt, ans;
private static int[] w, weight;
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
m = sc.nextInt();
n = sc.nextInt();
w = new int[n];
weight = new int[1 << (n / 2 + 2)];
for(int i = 0; i < n; i++) w[i] = sc.nextInt();
Arrays.sort(w);
reverse(w);
k = n / 2 + 2;
dfs1(0, 0);
Arrays.sort(weight, 0, cnt);
cnt = unique(weight);
dfs2(k, 0);
System.out.println(ans);
}
private static 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((long)weight[mid] + s <= m){
l = mid;
}else{
r = mid - 1;
}
}
ans = Math.max(ans, weight[r] + s);
return;
}
dfs2(u + 1, s);
if((long)s + w[u] <= m) dfs2(u + 1, s + w[u]);
}
private static void dfs1(int u, int s){
if(u == k){
weight[cnt++] = s;
return;
}
dfs1(u + 1, s);
if((long)s + w[u] <= m) dfs1(u + 1, s + w[u]);
}
private static int unique(int[] w){ //返回不重复数组长度
int t = 0;
for(int i = 1; i < cnt; i++){
if(w[t] != w[i]) w[++t] = w[i];
}
return t + 1;
}
private static void reverse(int[] w){
int l = 0, r = w.length - 1;
while(l < r){
int tmp = w[l];
w[l] = w[r];
w[r] = tmp;
l++; r--;
}
}
}