• 1257 背包问题 V3(二分)


    1257 背包问题 V3
    3 秒 131,072 KB 80 分 5 级题

    题意 :

    从n个物品中选出k个,使单位体积价值最大

    思路:

    一开始正面想,试过很多种,排序什么的、、总是结果不对,最后想到二分答案


    二分的规则是使index的前接近0即可

    ps:blocks[i].w物体的价值 block[i].p物体的体积 p二分答案

    假设p是我们要的答案,那么block[i].p*pblock[i]应该占有的价值
    blocks[i].w - block[i].p * p 为现在与目标价值的差
    这个差约小说明越接近答案,根据这一位进行排序,只要前k个。记录当前总体积和总价值即可。

    import java.util.Arrays;
    import java.util.Scanner;
    
    public class Main {
        static int n, k;
        static int ansA = 0, tA = 0;
        static int ansB = 0, tB = 0;
        static Block[] blocks = null;
    
        public static void main(String[] args) {
            Scanner cin = new Scanner(System.in);
            n = cin.nextInt();
            k = cin.nextInt();
            blocks = new Block[n];
            for (int i = 0; i < n; i++) {
                int a = cin.nextInt();
                int b = cin.nextInt();
                blocks[i] = new Block(a, b, 0);
            }
            cin.close();
            double left = 0, right = 50000.0;
            for (int i = 1; i < 100; i++) {
                double mid = (left + right) / 2.0;
                if (check(mid)) {
                    ansA = tA;ansB = tB;tA = tB = 0;
                    left = mid;
                } else {
                    ansA = tA;ansB = tB;tA = tB = 0;
                    right = mid;
                }
            }
            int x = gcd(ansA, ansB);
            System.out.println(ansB / x + "/" + ansA / x);
        }
    
        public static boolean check(double p) {
            for (int i = 0; i < n; i++) {
                blocks[i].dis = 1.0 * blocks[i].w - blocks[i].p * p;
            }
            Arrays.sort(blocks);
            double sum = 0;
            for (int i = 0; i < k; i++) {
                tA += blocks[i].w;
                tB += blocks[i].p;
                sum += blocks[i].dis;
            }
            if (sum > 0) return true;
            return false;
        }
    
        static int gcd(int a, int b) {
            return b == 0 ? a : gcd(b, a % b);
        }
    
        static class Block implements Comparable<Block> {
            int w;
            int p;
            double dis;
    
            public Block(int w, int p, double dis) {
                this.w = w;
                this.p = p;
                this.dis = dis;
            }
    
            @Override
            public int compareTo(Block o) {
                if (dis > o.dis) return 1;
                return -1;
            }
        }
    }
    
    
    
  • 相关阅读:
    506Relative Ranks(LeetCode)
    计算二进制中1的个数
    vector<vector<int>> 简单知识介绍
    167. Two Sum II
    561. Array Partition I(LeetCode)
    sizeof 用法部分总结
    530. Minimum Absolute Difference in BST(LeetCode)
    JS计算两个日期之间的天数
    路演会上会登记结论的委员信息页面
    eclipse安装SVN插件
  • 原文地址:https://www.cnblogs.com/somliy/p/10013380.html
Copyright © 2020-2023  润新知