lintcode 1382 · 大容量背包【hard vip 背包问题,只能单纯用递归才能通过】

题目链接,描述

https://www.lintcode.com/problem/1382

给出一个背包容量s, 给出n件物品,第i件物品的价值为vi,第i件物品的体积为ci,问这个背包最多能装多少的价值的物品,输出这个最大价值。(每个物品只能用一次)




1 <= s, vi, ci <= 10^13
1 <= n <= 31
样例
样例 1:

输入:s = 10, v = [1,2,3], c = [3,5,7]。
输出:4
解释:将第0个物品和第2个物品放进背包。
样例 2:

输入: s = 10, v = [1,5,3], c = [4,5,7]。
输出:6
解释:将第0个物品和第1个物品放进背包。

思路

和其他背包问题很类似,比如背包问题II

答案

public class Solution {
    /**
     * @param s: The capacity of backpack
     * @param v: The value of goods 
     * @param c: The capacity of goods
     * @return: The answer
     */
    public long getMaxValue(int s, int[] v, int[] c) {
         return f1(s,v,c); //递归版本,能通过,打败16.6
       //return f2(s,v,c); //动态规划版本,不能通过,报内存不足。后面有时间再找原因,这种写法,在类似的背包问题里能通过
    }

    //动态规划版本
    public static long f2(int s, int[] v, int[] c){
        int n= c.length;
        long[][] dp = new long[n+1][s+1];

        for (int i = n-1; i >=0 ; i--) {
            for (int rest = 0; rest <=s ; rest++) {
                long p1 = dp[i+1][rest];
                long p2 =0;
                long next = (rest-c[i] <0) ?-1:(dp[i+1][rest-c[i]]);
                if(next!=-1){
                    p2 = next+ v[i];
                }

                dp[i][rest] = Math.max(p1,p2);
            }
        }

        return dp[0][s];
    }

    //递归版本
    public static long f1(int s, int[] v, int[] c){
        return dfs(0,s,v,c);
    }
    public static long dfs(int index,int rest,int[] v,int[] c){
        if(rest<0) return -1;
        if(index== v.length)
            return 0;



        long p1 = dfs(index+1,rest,v,c);

        long p2 =0;
        long next = dfs(index+1,rest-c[index],v,c);
        if(next!=-1){
            p2 = next+v[index];
        }

        long max = Math.max(p1,p2);

        return max;
    }
}

你可能感兴趣的:(算法)