背包问题1

  • 题目
    • 给定两个长度都为N的数组weights和values,
      weights[i]和values[i]分别代表 i号物品的重量和价值。
      给定一个正数bag,表示一个载重bag的袋子,
      你装的物品不能超过这个重量。
      返回你能装下最多的价值是多少?
  • 思路:
  • 接收信息:cur,weight(剩余可用承重),value(已拿价值)
  • 决策:每个位置选拿/不拿两个分支
  • base case:如果weight<0则返回失败标记,上层对失败标记进行处理,value不加这个商品。如果cur到末尾retuen 0
    • 问题:这里可以等到末尾了还有效再在list里记录当前value,中途一旦失效就不记录
    • 答案:应该没有问题,最优解剩余重量>=0所以一定会达到末尾且到末尾了依然有效。但这是贪心策略
  • 传递信息:cur++,weight增减,value增减
  • dp:以weight,cur建表。value为值
  • 普遍依赖关系:依赖下一行正下或正下往左偏weight
    • 如果(rest - w[index] < 0 )
      • p1=v[index] +dp[index + 1][rest - w[index]
    • p2=dp[index + 1][rest];
    • max(p1,p2)

代码

public static int dp(int[] w, int[] v, int bag) {
		if (w == null || v == null || w.length != v.length || w.length == 0) {
			return 0;
		}
		int N = w.length;
		int[][] dp = new int[N + 1][bag + 1];
		for (int index = N - 1; index >= 0; index--) {
			for (int rest = 0; rest <= bag; rest++) {
				int p1 = dp[index + 1][rest];
				int p2 = 0;
				int next = rest - w[index] < 0 ? -1 : dp[index + 1][rest - w[index]];
				if (next != -1) {
					p2 = v[index] + next;
				}
				dp[index][rest] = Math.max(p1, p2);
			}
		}
		return dp[0][bag];
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值