每天一道算法题(一) (动态规划算法)背包问题Java实现

来源:互联网 发布:淘宝 非典 编辑:程序博客网 时间:2024/06/04 19:35

转载地址http://blog.csdn.net/u014394715/article/details/51162960

动态规划


动态规划在wiki上的定义:

dynamic programming is a method for solving a complex problem by breaking it down into a collection of simpler subproblems, solving each of those subproblems just once, and storing their solutions - ideally, using a memory-based data structure. The next time the same subproblem occurs, instead of recomputing its solution, one simply looks up the previously computed solution。


昨天接触到了动态规划的概念,研究了昨天一晚上以及今天一上午,总算对这个问题有些收获。 
动态规划背后的基本思想非常简单。大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解。 
从空集合开始,每增加一个元素就求它的最优解,直到所有元素加进来,就得到了总的最优解。


01背包问题

01背包问题即的01即每件物品最多放1件,否则不放入。 
让我真正了解动态规划概念的是mu399的博客

问题:有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?


重新定义问题:

  1. 有承重分别为1-10的背包10个
  2. 编号分别为a,b,c,d,e的物品各一个
nameweightvaluea26b23c65d54e46

3. 从e物品开始依次放入1-10个背包,分别得到最大的价值总和 
4. 把d物品放入依次放入存在e物品的1-10个背包,如果价值更高,替换掉e() 
5. c,b,a同理。。。

nameweightvalue12345678910e460006666666d54000666661010c65000666661011b23033669991011a26066991212151515

思路: 
1. 01背包的状态转换方程 f[i,j] = Max{f[i-1,j-Wi]+Pi( j >= Wi ), f[i-1,j] }

f[i,j]:在前i件物品中选择若干件放在承重为 j 的背包中,可以取得的最大价值。 
Pi表示第i件物品的价值。 
决策:为了背包中物品总价值最大化,第 i件物品应该放入背包中吗 ? 
2. 以a8(行为a,列为的8的单元格)举例 
f[i,j] = a8 = 15 
f[i-1,j] = b8 = 9 
f[i-1,j-Wi] 表示我有一个承重为6的背包(等于当前背包承重减去物品a的重量),当只有物品b,c,d,e四件可选时,这个背包能装入的最大价值 
f[i-1,j-Wi] +Pi =b(8 - 2) + 6 = b6 + 6 = 15

我遇到的一道网易编程题:

一种双核CPU的两个核能够同时的处理任务,现在有n个已知数据量的任务需要交给CPU处理,假设已知CPU的每个核1秒可以处理1kb,每个核同时只能处理一项任务。n个任务可以按照任意顺序放入CPU进行处理,现在需要设计一个方案让CPU处理完这批任务所需的时间最少,求这个最小的时间。 

输入描述:
输入包括两行:第一行为整数n(1 ≤ n ≤ 50)第二行为n个整数length[i](1024 ≤ length[i] ≤ 4194304),表示每个任务的长度为length[i]kb,每个数均为1024的倍数。


输出描述:
输出一个整数,表示最少需要处理的时间

输入例子:
53072 3072 7168 3072 1024

输出例子:
9216

此题的java代码实现

import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNext()) {int n = sc.nextInt();int[] arr = new int[n];int sum = 0;for (int i = 0; i < arr.length; i++) {arr[i] = sc.nextInt() >> 10;sum += arr[i];}//转化为背包问题int[] dp = new int[sum / 2 + 1];for (int i = 0; i < n; i++) {for (int j = sum / 2; j >= arr[i]; j--) {dp[j] = Math.max(dp[j], dp[j - arr[i]] + arr[i]);}}System.out.println(Math.max(dp[sum / 2], sum - dp[sum / 2]) << 10);}}}


背包的java代码实现

public class getPgAnswer{    @Test    public void testPackage() {        Package[] pg =  {new Package("e",4,6),                         new Package("d",5,4),                         new Package("c",6,5),                         new Package("b",2,3),                         new Package("a",2,6)                         };        // 第一个参数表示从pg[0]开始依次放入的物品,        // 第二个参数代表背包的承重,放弃第0列数组        int[][] state = new int[pg.length][11];        int newValue = 0;        /**         *  01背包的状态转换方程         *  f[i,j] = Max{         *               f[i-1,j-Wi]+Pi( j >= Wi ),          *               f[i-1,j] }         */        for (int i = 0; i < pg.length; i++) {            // 背包的承重量            for (int j = 1; j < state[i].length; j++) {                if (i == 0) {                    if (pg[i].getWeight() <= j) {                        state[i][j] = pg[i].getValue();                    }                }else{                    state[i][j] = state[i - 1][j];                    if (j < pg[i].getWeight()) {                        continue;                    }                    newValue = state[i - 1][j - pg[i].getWeight()]                            + pg[i].getValue();/*                  if (newValue  >= state[i - 1][j]) {                        state[i][j] = newValue;                    }else{                        state[i][j] = state[i - 1][j];                    }*/                    state[i][j] = Math.max(newValue, state[i - 1][j]);                }            }        }        for (int i = 0; i < state.length; i++) {            System.out.println(Arrays.toString(state[state.length - 1 - i]));        }    }}class Package {    private String name;    private int weight;    private int value;    public Package(String name,int weight,int value){        this.name = name;        this.weight = weight;        this.value = value;    }    public String getName() {        return name;    }    public int getWeight() {        return weight;    }    public int getValue() {        return value;    }
1 0
原创粉丝点击