口罩问题动态规划

package m2020;
//【问题描述】
//某市市长获得了若干批口罩,每一批口罩的数目如下: 9090400 8499400 5926800 8547000 4958200 4422600 5751200 4175600 6309600 5865200 6604400 4635000 10663400 8087200 4554000 现在市长要把口罩分配给市内的 2 所医院。由于物流限制,每一批口罩只 能全部分配给其中一家医院。市长希望 2 所医院获得的口罩总数之差越小越好。 请你计算这个差最小是多少?

动态规划背包问题

步骤1-找子问题:子问题必然是和物品有关的,对于每一个物品,有两种结果:能装下或者不能装下。第一,包的容量比物品体积小,装不下,这时的最大价值和前i-1个物品的最大价值是一样的。第二,还有足够的容量装下该物品,但是装了不一定大于当前相同体积的最优价值,所以要进行比较。由上述分析,子问题中物品数和背包容量都应当作为变量。因此子问题确定为背包容量为j时,求前i个物品所能达到最大价值。

步骤2-确定状态:由上述分析,“状态”对应的“值”即为背包容量为j时,求前i个物品所能达到最大价值,设为dp[j]。初始时,dp0为0,没有物品也就没有价值。

步骤3-确定状态转移方程:由上述分析,第i个物品的体积为w,价值为v,则状态转移方程为

1.j<w的状态转移方程不再需要了。2.为保证每个物品只能使用一次,我们倒序遍历所有j的值,这样在更新dp[j]的时候,dp[j-list[i].w]的值尚未被修改,就不会出现一个物品重复使用的问题。

优化后的状态转移方程:dp[j] = max{ dp[j-list[i].w] + v, dp[j] }

import java.util.LinkedList;
import java.util.List;

public class B_2020_mask {
public static void main(String[] args) {
int sum = 0, su = 0;
int[] nums = {0, 9090400, 8499400, 5926800, 8547000, 4958200,
4422600, 5751200, 4175600, 6309600, 5865200, 6604400, 4635000,
10663400, 8087200, 4554000};
for(int i = 0; i < nums.length; i++) {
sum += nums[i];
}
su = sum / 2;
int[] dp = new int[su+1];
for(int i = 1; i < nums.length; i++) {
for(int j = su; j >= nums[i]; j–) {
dp[j] = Math.max(dp[j], dp[j-nums[i]] + nums[i]);
}
}
System.out.println(2 * (su - dp[su]));
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值