🍑 送礼物
达达帮翰翰给女生送礼物,翰翰一共准备了 N N N 个礼物,其中第 i i i 个礼物的重量是 KaTeX parse error: Undefined control sequence: \[ at position 2: G\̲[̲i\]。
达达的力气很大,他一次可以搬动重量之和不超过 W W W 的任意多个物品。
达达希望一次搬掉尽量重的一些物品,请你告诉达达在他的力气范围内一次性能搬动的最大重量是多少。
输入格式
第一行两个整数,分别代表 W W W 和 N N N。
以后 N N N 行,每行一个正整数表示 KaTeX parse error: Undefined control sequence: \[ at position 2: G\̲[̲i\]。
输出格式
仅一个整数,表示达达在他的力气范围内一次性能搬动的最大重量。
数据范围
1
≤
N
≤
46
1 \le N \le 46
1≤N≤46,
1
≤
W
,
G
[
i
]
≤
2
31
−
1
1 \le W,G[i] \le 2^{31}-1
1≤W,G[i]≤231−1
输入样例:
20 5
7
5
4
18
1
输出样例:
19
import java.util.*;
class Main
{
static int N = 100;
static int n, m, k;
static Integer[] w = new Integer[N];
// static int[] ww = new int[1 << 25];// 存储能凑出的重量
static Integer[] ww = new Integer[1 << 25];
static HashSet<Integer> set = new HashSet<>();// 实现去重
static int cnt, ans;// cnt 记录能凑出的重量数
/**
* @param u 当前枚举的物品(未计算)
* @param s 当前的总重量
*/
static void dfs1(int u, int s)
{
if (u == k)
{
set.add(s);// 把重量存在 HashSet 里边去
return;
}
dfs1(u + 1, s);
if ((long) s + w[u] <= m)
dfs1(u + 1, s + w[u]);
}
/**
* @param u 表示当前枚举到的物品
* @param s 表示当前方案的总体积
*/
static void dfs2(int u, int s)
{
if (u == n)
{
int l = 0;
int r = cnt - 1;
while (l < r)
{
int mid = l + r + 1 >> 1;
// 找到 最大的 小于等于 (m-s) 的数
if (ww[mid] <= m - s)
l = mid;
else
r = mid - 1;
}
ans = Math.max(ans, ww[l] + s);
return;
}
dfs2(u + 1, s);
if ((long) s + w[u] <= m)
dfs2(u + 1, s + w[u]);
}
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
m = sc.nextInt();// 总体积
n = sc.nextInt();// 物品个数
for (int i = 0; i < n; i++)
w[i] = sc.nextInt();
Arrays.sort(w, 0, n, (o1, o2) -> o2 - o1);// 从大到小进行排序
k = n / 2 ;
dfs1(0, 0);
cnt = 1;
//Integer数组进行排序时一定要初始化为一个值,就算是全局数组也没有默认值
ww[0] = 0;
for (int x : set)
ww[cnt++] = x;
Arrays.sort(ww, 0, cnt, (o1, o2) -> o1-o2);// 这次是从小到大进行排序
dfs2(k, 0);
System.out.println(ans);
}
}
👨🏫 Bug-Free 的题解