01背包问题—题解

 背包问题
有n个物品,每个物品的重量为weight[i],每个物品的价值为value[i]。现在有一个背包,它所能容纳的重量为total,问:
当你面对这么多有价值的物品时,你的背包所能带走的最大价值是多少?
程序输入输出格式要求:
程序输入3行:
第一行是物品总数n, 第2行是每个物品的重量,第3行是每个物品的价值,第3行是背包的容量
程序输出2行:
第1行是背包所能带走的最大价值,第2行是装入最大价值时背包中的物品的序号(只需输出一个最优解即可)
例如:
用户输入:
5
2,2,6,5,4
6,3,5,4,6
10
则程序输出:
15

1,2,5


解题思路:  

1. 递归搜索。

2. 动态规划   (网上有很多好的资源)

3. 完全背包、多重背包也是一样的原理。不再解释。


源代码: 1.递归搜索

public class Main
{
static int n = 0;     // 物品的数目
static int weight[];  // 物品的重量
static int value[];   // 物品的价值

static int max = 0;   // 物品的最大价值
static int table[] = new int[100001];   // 此时物品的摆放
static int index = 0; // 物品标记
public static void main(String[] args)
  {
       Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        weight = new int [n];
        value = new int [n];
       for (int i = 0; i < n; i++) weight[i] = sc.nextInt();
       for (int i = 0; i < n; i++) value[i] = sc.nextInt();
       int total = sc.nextInt();
       sc.close();
       
       int nums[] = new int [n];   // 暂时放入物品的编号
       
       dfs(0, nums, 0, total);  // 深度搜索
       
       System.out.println(max);
       for (int i = 0; i < index; i++)
       {
      System.out.print((table[i]+1) + " ");
       }
       System.out.println();
}

private static void dfs(int num, int[] nums, int index, int total)
{
         if (num >= n)  // 没有物品搜索了。
         {
        check(nums, index);
        return;   
         }
         
         if (weight[num] > total) // 超重 return 
         {
        dfs(num+1, nums, index, total);  return ;
         }


          // 装
          nums[index++] = num;  
         dfs(num+1, nums, index, total-weight[num]);
         // 不装
          index--;
         dfs(num+1, nums, index, total);
}


private static void check(int[] nums, int index2)
{
int m = 0;
        for (int i = 0; i < index2; i++)
        { 
        m += value[nums[i]];
        }
        if (m > max)
        {
        max = m;
        // 拷贝数组
        index = index2;
        for (int i = 0; i < index2; i++)
        {
        table[i] = nums[i];
        }
        }
}
}


2.动态规划

public class Main
{
public static void main(String[] args)
  {
       Scanner sc = new Scanner(System.in);
       int  n = sc.nextInt();
       int[] weight = new int [n+1];
       int[] value = new int [n+1];
       for (int i = 1; i <= n; i++) weight[i] = sc.nextInt();
       for (int i = 1; i <= n; i++) value[i] = sc.nextInt();
       int total = sc.nextInt();
       sc.close();
       
       int dp[][] = new int[n+1][total+1];
       for (int i = 1; i < dp.length; i++)
       {
      for (int j = 1; j < dp[i].length; j++)
      {
      if (j >= weight[i])
            dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-weight[i]] + value[i]);
      else 
      dp[i][j] = dp[i-1][j];
      }
       }
       
       for (int i = 1; i < dp.length; i++)
       {
     for (int j = 1; j < dp[i].length; j++)
     {
    System.out.print(dp[i][j] + " ");  
     }
     System.out.println();
       }
       
}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值