给定n种物品和一个背包。物品 i 的重量是wi.......

题目描述:

给定n种物品和一个背包。物品 i 的重量是wi,其价值为vi,背包的容量为c. 应该如何选择装入背包中的物品,使其装入背包中的物品的总价值最大? 提示:可以选择物品 i 的一部分装入,而不一定要全部装入背包。

输入
背包的容量 物品的个数
物品的价值 物品的重量

输出
装入的物品 【1代表装入,0代表不装入,非0非1代表部分装入】

样例输入

50 3

60 10

100 20

120 30

样例输出

1 1 0.666667

题目来源

提示 输入重量和价值时,已经将物品按单位价值排序。

思路总结:
其实就是贪心算法的运用,每次我们都装入单位价值最大的,直到背包装满
但是有两种情况:

  1. 恰好装满,这种比较男的
  2. 最后一个物品,只装入部分

遇见的问题:
Java代码,提示一直是答案错误,折腾了很久,觉得思路没有错
最后发现是格式的问题,所以换的c++,由于老师用的是c++

问题解决所学到知识:

1.控制格式的输出:如果小数点后面有多的零,自动删除, 例如(1.220000 ----> 1.22, 1.0000 ----> 1.0, 0.000 ------>0 )

 BigDecimal bigDecimal = new BigDecimal(String.valueOf(x));
 System.out.print(bigDecimal.stripTrailingZeros().toPlainString()+" ");

2.二维数组的排序:使用java的Arrays.sort(), 中的Comparator<float[]>()

//   进行二维数组的排序
返回值大于0,则需要交换位置, 返回值小于0,表示顺序正确 ,返回值等于0 ,表示相等

/**
  * 返回值大于0,则需要交换位置, 返回值小于0,表示顺序正确 ,返回值等于0 ,表示相等
  * */
		float[][] a = new float[n][2];
        Arrays.sort(a, new Comparator<float[]>() {
            @Override
            public int compare(float[] o1, float[] o2) {
               if (o2[2] > o1[2]){
                   return 1;
               }else{
                   return -1;
               }
            }
        });

参考代码:

java:默认输入的没有按照单价排序

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

/**
 * @author chenzi
 */
public class Main {
    public static void main(String[] args) {
        int maxWeight, n, i, j;
        Scanner scanner = new Scanner(System.in);
        maxWeight = scanner.nextInt();
        n = scanner.nextInt();
        float[][] a = new float[n][4];
        for (i = 0; i < n; i++) {
            for (j = 0; j < 2; j++) {
                a[i][j] = scanner.nextFloat();
            }
            /*a[][2]用于存单价:价值/重量*/
            a[i][2] = a[i][0] / a[i][1];
            a[i][3] = i;
        }
        float[] result = new Main().Max_backpack(a, n, maxWeight);
        for (float x : result
        ) {
            BigDecimal bigDecimal = new BigDecimal(String.valueOf(x));
            System.out.print(bigDecimal.stripTrailingZeros().toPlainString()+" ");
        }
    }

    private float[] Max_backpack(float[][] a, int n, int maxWeight) {
        float[] result = new float[n];
        int current_maxWeight = 0;
//        进行二维数组的排序
        /**
         * 返回值大于0,则需要交换位置, 返回值小于0,表示顺序正确 ,返回值等于0 ,表示相等
         */
        Arrays.sort(a, new Comparator<float[]>() {
            @Override
            public int compare(float[] o1, float[] o2) {
               if (o2[2] > o1[2]){
                   return 1;
               }else{
                   return -1;
               }
            }
        });
        for (int i = 0; i < n; i++) {
            if (current_maxWeight < maxWeight && current_maxWeight + a[i][1] <= maxWeight) {
                current_maxWeight += a[i][1];
                result[(int)a[i][3]] = 1;
            } else if (current_maxWeight < maxWeight && current_maxWeight + a[i][1] > maxWeight) {
                result[(int)a[i][3]] = (float) (maxWeight - current_maxWeight) / a[i][1];
                current_maxWeight = maxWeight;
            }else {
                break;
            }
        }
        return result;
    }
}

c++:输入已经按照单价排序

#include <iostream>
using namespace std;
/*------------------------------------------------------------------------------------------
   c++ 传入二维数组必须是指定第二维或者使用指针
  由于很久没有使用c++了,很多忘了,所以索性就在函数内输出了
  不成文规定:不能再函数中做输入输出的,应该返回结果的 
---------------------------------------------------------------------------------------*/
void maxLoading(float a[][2], int n, float maxWeight)
{
    // c++不能返回数组,只能返回指针
    float current_maxWeight = 0;
    float result[n];
    for (int i = 0; i < n; i++)
    {
        if (current_maxWeight < maxWeight && current_maxWeight + a[i][1] <= maxWeight)
        {
            current_maxWeight += a[i][1];
            result[i] = 1;
        }
        else if (current_maxWeight < maxWeight && current_maxWeight + a[i][1] > maxWeight)
        {
            result[i] = (maxWeight - current_maxWeight) / a[i][1];
            current_maxWeight = maxWeight;
        }
        else
        {
            // 简单分析得不满足前面两个判断,此时背包一定达到 maxWeight
            break;
        }
    }
    // 理应不该在这里做输出的
    for (float x : result)
    {
        cout << x << " ";
    }
}

int main()
{
    int n; 
    float maxWeight;
    cin >> maxWeight >> n;
    float a[n][2];
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < 2; j++)
        {
            cin >> a[i][j];
        }
    }
    maxLoading(a, n, maxWeight);
}

  • 11
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值