zvvq.cn
0-1 袋子问题
主题描述 内容来自samhan
Ming 是一位科学家,他需要参加一个重要的国际科学会议来展示他的最新研究成果。他需要带一些研究资料,但他的行李箱空间有限。这些研究资料包括实验设备、文献、实验样本等,各自占据不同的空间,具有不同的价值。
Ming的行李空间为N。问Ming应该如何选择携带最有价值的研究资料。每个研究材料只能选择一次,并且只有选择或不选择两种选择,并且不能进行裁剪。
输入描述 内容来自samhan
第一行包含两个正整数,第一个整数M代表研究材料的类型,第二个正整数N代表Ming的行李空间。第二行包含 M 个正整数,代表每种研究材料占用的空间。
zvvq好,好zvvq
第三行包含M个正整数,代表每个研究材料的价值。
内容来自zvvq,别采集哟
输出描述 内容来自zvvq
输出一个整数,代表Ming可以携带的研究材料的最大值。输入示例 内容来自samhan666
6 1 zvvq.cn
2 2 3 1 5 2
内容来自zvvq
2 3 1 5 4 3输出示例 zvvq.cn
5提示 内容来自samhan
小明可以携带6个研究材料,但行李空间只有1个,而占用1个空间的研究材料价值5个,所以最终答案是输出5。数据范围: 内容来自zvvq,别采集哟
1 1 研究材料占用空间和研究材料价值均小于等于1000。
1
2 zvvq
3 copyright zvvq
4
zvvq.cn
5
6
本文来自zvvq
7 本文来自zvvq
8 内容来自samhan
9
zvvq
10 内容来自samhan666
11 zvvq好,好zvvq
12 zvvq
13
14
copyright zvvq
15 zvvq.cn
16 内容来自zvvq,别采集哟
17 zvvq
18 内容来自zvvq,别采集哟
19 zvvq
20 zvvq
21 内容来自zvvq,别采集哟
22
23 本文来自zvvq
24 zvvq.cn
25
内容来自zvvq,别采集哟
26 内容来自samhan666
27 本文来自zvvq
28 内容来自zvvq,别采集哟
29
30
31 内容来自samhan666
32
zvvq
33
34
本文来自zvvq
35
公开课主{
内容来自zvvq,别采集哟
公共静态无效主(字符串[]参数){
copyright zvvq
/ 代码 /
扫描仪 s = new Scanner(System.in);
zvvq.cn
int M = s.nextInt(); 内容来自zvvq,别采集哟
int N = s.nextInt(); zvvq
// 清除缓冲区符号 /n
本文来自zvvq
s.nextLine();
字符串 w = s.nextLine();
字符串 v = s.nextLine();
内容来自samhan666
int[] 权重 = Arrays.stream(w.split(" "))
.mapToInt(整数::valueOf)
zvvq
.toArray(); 内容来自zvvq,别采集哟
int[] value = Arrays.stream(v.split(" "))
zvvq好,好zvvq
.mapToInt(整数::valueOf) 内容来自samhan666
.toArray(); copyright zvvq
int[][] dp = 新 int[M][N+1]; 内容来自samhan666
for(int i=权重[0]; i j){
内容来自zvvq,别采集哟
dp[i][j] = dp[i-1][j]; 内容来自zvvq
}别的{
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - 权重[i]] + 值[i]); zvvq好,好zvvq
}
} 内容来自zvvq
}
内容来自samhan666
System.out.println(dp[M-1][N]);
} 内容来自zvvq,别采集哟
} copyright zvvq
1,dp数组意味着我们可以获得item i和目标bag size j的最大值。行表示物品,列表示包的尺寸。
zvvq
2,对于init,我们初始化第一行和第一列(但实际上我们默认初始化列为0,这意味着) 内容来自samhan
3,回归关系为:对于每一项: 本文来自zvvq
a、如果物品的重量大于包的尺寸,则无法选择该物品,当前尺寸为之前选择的物品集合的尺寸。
这里,是双循环的顺序,因为我们可以用一个二维数组来记录所有结果,从上一行开始查找当前行。 zvvq好,好zvvq
另外,我们可以使用一维数组来实现。
1 内容来自samhan666
2 内容来自zvvq
3
4 内容来自zvvq
5 内容来自zvvq
6
内容来自samhan666
for(int i=1; i<m i for j="1;" if> j){ zvvq
dp[i][j] = dp[i-1][j];
本文来自zvvq
}别的{
内容来自zvvq,别采集哟
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - 权重[i]] + 值[i]);
zvvq
} 内容来自samhan
</m>
改成
1
int[] dp = new int[target+1]; zvvq
1 zvvq
2 内容来自zvvq,别采集哟
3
4 本文来自zvvq
5 内容来自zvvq
6
7 zvvq.cn
8
内容来自samhan
for(int i=1; i<nums.length i for j="目标;">=1; j--){ zvvq好,好zvvq
if(nums[i] > j){ 本文来自zvvq
继续; 内容来自samhan666
} zvvq.cn
dp[j] = Math.max(dp[j], dp[j-nums[i]] + nums[i]); 内容来自samhan
} 内容来自zvvq,别采集哟
} zvvq好,好zvvq
</nums.length> zvvq好,好zvvq
416. 划分子集和相等
给定一个整数数组 nums,如果可以将数组划分为两个子集,使得两个子集中的元素之和相等,则返回 true,否则返回 false。
示例1:
输入:nums = [1,5,11,5] 内容来自samhan666
输出:true
内容来自zvvq
说明:数组可以分为 [1, 5, 5] 和 [11]。 内容来自zvvq,别采集哟
示例2:输入:nums = [1,2,3,5] zvvq
输出:假
内容来自samhan
说明:数组不能划分为等和子集。限制: 内容来自zvvq
1 1 原始页面 本文来自zvvq
1
2
3 内容来自zvvq,别采集哟
4 zvvq
5 内容来自zvvq,别采集哟
6
zvvq好,好zvvq
7 内容来自zvvq,别采集哟
8 本文来自zvvq
9 zvvq好,好zvvq
10 zvvq
11 zvvq好,好zvvq
12
13 内容来自zvvq,别采集哟
14 本文来自zvvq
15
zvvq.cn
16 zvvq
17 本文来自zvvq
18
19
public boolean canPartition(int[] nums) {
int sum = Arrays.stream(nums).sum();
内容来自zvvq,别采集哟
如果(总和%2==1){ 本文来自zvvq
返回假;
内容来自samhan
} 内容来自samhan
int 目标=总和>>1; 内容来自samhan
int[][] dp = new int[nums.length][目标+1];
for(int i=nums[0]; i j){ 内容来自zvvq
dp[i][j] = dp[i-1][j]; 内容来自samhan666
}别的{
zvvq好,好zvvq
dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-nums[i]] + nums[i]);
内容来自samhan
}
} 本文来自zvvq
}
copyright zvvq
返回 dp[nums.length-1][目标] == 目标;
本文来自zvvq
}
内容来自samhan
以上就是LeetCode Day动态编程第31部分的详细内容,更多请关注其它相关文章! zvvq.cn