• POJ 1252 Euro Efficiency ( 完全背包变形 && 物品重量为负 )


    题意 : 给出 6 枚硬币的面值,然后要求求出对于 1~100 要用所给硬币凑出这 100 个面值且要求所用的硬币数都是最少的,问你最后使用硬币的平均个数以及对于单个面值所用硬币的最大数。

    分析 : 

    问题建模就是属于完全背包了,但是和普通的完全背包不一样,这题可以使用硬币的负数值,其实面对负数面值的情况,解决方法将更新数序和普通完全背包的更新顺序相反即可,然后正反更新两次就能得出最后的答案了。在普通物品重量只有正数的情况下对于一个 dp[i] 是从下标值小于 i 的状态转移而来,为了达到物品能够无限取这一条件 ( 可以参考《挑战程序设计竞赛》里面对于完全背包递推式子的解释 ) ,而负数重量的时候 dp[i] 是从下标值大于 i 的状态转移而来,故更新方向需和正数重量相反,其实这么说也是很抽象的,建议还是先去看看《挑战》里面对于完全背包原来的分析可能比较好理解。然后有一点值得注意的就是如果 dp 数组下标的更新需要开到起码 1400 ==> 考虑 1、96、97、98、99、100 这一个例子,如果要凑成 ( 1 + 96 ) / 2 的话大概需要 25个左右 也就是需要使用大概需要25/2=13个面值为 100 的硬币,价值能达到 1300.....

    import java.io.*;
    import java.lang.reflect.Array;
    import java.util.*;
    import java.math.*;
    import java.util.Arrays;
    public class Main {
        public static void main(String[] args){
            Scanner cin = new Scanner (new BufferedInputStream(System.in));
            int[] dp = new int[2333];
            int[] arr1 = new int[6];
            int[] arr2 = new int[6];
            int nCase;
            final int num = 6;
            nCase = cin.nextInt();
            for(int Case=1; Case<=nCase; Case++){
                
                for(int i=0; i<num; i++) arr1[i] = cin.nextInt();
                for(int i=0; i<num; i++) arr2[i] = -arr1[i];
                
                for(int i=0; i<2333; i++) dp[i] = 1000000;
                dp[0] = 0;
                for(int i=0; i<num; i++)
                    for(int j=arr1[i]; j<=2000; j++)
                        dp[j] = Math.min(dp[j], dp[j-arr1[i]] + 1);
                    
                for(int i=0; i<num; i++)
                    for(int j=2000-arr2[i]; j>=0; j--)
                        dp[j] = Math.min(dp[j], dp[j-arr2[i]] + 1);
                
                int MaxNUM = 0;
                double Sum = 0;
                for(int i=0; i<=100; i++){
                    MaxNUM = Math.max(dp[i], MaxNUM);
                    Sum += (double)dp[i];
                }
                
                System.out.printf("%.2f %d
    ", Sum/100.0, MaxNUM);
                
            }
        }
    }
    View Code
  • 相关阅读:
    117. 填充每个节点的下一个右侧节点指针 II
    116. 填充每个节点的下一个右侧节点指针
    114. 二叉树展开为链表
    9.5 NLP slide: 第二课 语言模型
    165. 比较版本号
    143. 重排链表
    147. 对链表进行插入
    127. 单词接龙
    129. 求根到叶子节点数字之和
    95. 不同的二叉搜索树 II 递归
  • 原文地址:https://www.cnblogs.com/qwertiLH/p/8309292.html
Copyright © 2020-2023  润新知