题解 | #兑换零钱(一)# 完全背包变形 [P0]

兑换零钱(一)

http://www.nowcoder.com/practice/3911a20b3f8743058214ceaa099eeb45

完全背包变形
dp[i][v]: 用前i个硬币组合出价值v所需的最少硬币数
dp[0][0]=1, dp[0][v]=0 for v>0.
dp[i][v] = Min {
  (a) dp[i-1][v],      // 不用i硬币
  (b) dp[i][v-arr[i]]  // 用i硬币
}

完全与01背包的核心区别是
  - 01背包不能dirty write (一个硬币只能使用0或1次), 
    i.e. (b)选项为 dp[i-1][v-arr[i]]
  - 完全背包就是要dirty write (一个硬币可以使用多次)
    i.e. (b)选项为 dp[i][v-arr[i]]
import java.util.*;

public class Solution {
  
    // 完全背包变形
    public int minMoney (int[] arr, int aim) {
      int[] mem = new int[aim+1];
      // 这里如果用Integer.MAX_VALUE,15行会overflow.
      // 因为 aim <= 5000, 所以结果不可能大于5000.
      Arrays.fill(mem, 5001);
      mem[0] = 0;  // {0, 5001, 5001 ... ... 5001}
      
      for (int i = 0; i < arr.length; i++) {
        for (int x = arr[i]; x <= aim; x++) {
          mem[x] = Math.min(mem[x], mem[x-arr[i]]+1);
        }
      }
      
      return mem[aim] == 5001 ? -1 : mem[aim];
    }
}
DP是真的烦 文章被收录于专栏

只是为了把DP的题集中一下方便自己复习

全部评论

相关推荐

ArisRobert:统一解释一下,第4点的意思是,公司按需通知员工,没被通知到的员工是没法去上班的,所以只要没被通知到,就自动离职。就是一种比较抽象的裁员。
点赞 评论 收藏
分享
评论
2
收藏
分享
牛客网
牛客企业服务