背包问题之求具体方案数

题库

package com.zhang.reflection.面试.算法模版.背包问题模版;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
 * 技巧: 如果从需要求字典序最小, dp求解从后往前求
 * 即可从前往后推方案。
 * 求解出来dp[1][m]就是最大价值
 *有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。
 *
 * 第 i 件物品的体积是 vi,价值是 wi。
 *
 * 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
 *
 * 输出 字典序最小的方案。这里的字典序是指:所选物品的编号所构成的序列。物品的编号范围是 1…N。
 *
 * 输入格式
 * 第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。
 *
 * 接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。
 *
 * 输出格式
 * 输出一行,包含若干个用空格隔开的整数,表示最优解中所选物品的编号序列,且该编号序列的字典序最小。
 *
 * 物品编号范围是 1…N。
 * 输入:
 * 4 5
 * 1 2
 * 2 4
 * 3 4
 * 4 6
 * 输出:
 * 1 4
 */
public class 求具体方案 {
    static BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
    static int N = 1010, V = 1010;
    static int[] w = new int[N], v = new int[N];
    static int[][] dp = new int[N][V];
    public static void main(String[] args) throws Exception{
        String[] ss = read.readLine().split(" ");
        Scanner sc=new Scanner(System.in);
        int n = Integer.valueOf(ss[0]);
        int m = Integer.valueOf(ss[1]);
        for(int i = 1; i <= n; i++){
            ss = read.readLine().split(" ");
            v[i] = Integer.valueOf(ss[0]);
            w[i] = Integer.valueOf(ss[1]);
        }

        for(int i = n; i >= 1; i--){
            for(int j = 0; j <= m; j++){
                //不选
                dp[i][j] = dp[i + 1][j];
                if(j - v[i] >= 0){
                    //选
                    if(dp[i + 1][j -v[i]] + w[i] > dp[i][j]){
                        dp[i][j] = dp[i + 1][j -v[i]] + w[i];
                    }
                }
            }
        }
        List<Integer> list = new ArrayList();
        int curV = m; //当前最大体积
        for(int i = 1; i <= n; i++){
            //字典序最小,从小到大遍历,能选则选
            if(curV - v[i] >= 0 && dp[i][curV] == dp[i + 1][curV - v[i]] + w[i]){
                list.add(i);
                curV -= v[i];   //选了后,最大体积就要减少v[i];
            }
        }
        for(int i = 0; i < list.size(); i++){
            System.out.print(list.get(i) + " ");
        }
    }
}
全部评论

相关推荐

点赞 评论 收藏
分享
11-04 14:10
东南大学 Java
_可乐多加冰_:去市公司包卖卡的
点赞 评论 收藏
分享
评论
点赞
收藏
分享
正在热议
# 25届秋招总结 #
441069次浏览 4495人参与
# 春招别灰心,我们一人来一句鼓励 #
41545次浏览 524人参与
# 阿里云管培生offer #
119968次浏览 2219人参与
# 地方国企笔面经互助 #
7937次浏览 18人参与
# 同bg的你秋招战况如何? #
75837次浏览 554人参与
# 虾皮求职进展汇总 #
114640次浏览 885人参与
# 北方华创开奖 #
107337次浏览 599人参与
# 实习,投递多份简历没人回复怎么办 #
2454217次浏览 34849人参与
# 实习必须要去大厂吗? #
55703次浏览 960人参与
# 提前批简历挂麻了怎么办 #
149846次浏览 1977人参与
# 投递实习岗位前的准备 #
1195775次浏览 18547人参与
# 你投递的公司有几家约面了? #
33182次浏览 188人参与
# 双非本科求职如何逆袭 #
661978次浏览 7394人参与
# 如果公司给你放一天假,你会怎么度过? #
4734次浏览 55人参与
# 机械人春招想让哪家公司来捞你? #
157608次浏览 2267人参与
# 如果你有一天可以担任公司的CEO,你会做哪三件事? #
11417次浏览 276人参与
# 发工资后,你做的第一件事是什么 #
12467次浏览 61人参与
# 工作中,努力重要还是选择重要? #
35657次浏览 384人参与
# 参加完秋招的机械人,还参加春招吗? #
20096次浏览 240人参与
# 我的上岸简历长这样 #
451947次浏览 8088人参与
# 实习想申请秋招offer,能不能argue薪资 #
39252次浏览 314人参与
# 非技术岗是怎么找实习的 #
155859次浏览 2120人参与
牛客网
牛客企业服务