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