zoukankan      html  css  js  c++  java
  • Arithmetic_Greedy_Painter

    Peking University 2709 :

      DescriptionThe local toy store sells small fingerpainting kits with between three and twelve 50ml bottles of paint, each a different color. The paints are bright and fun to work with, and have the useful property that if you mix X ml each of any three different colors, you get X ml of gray. (The paints are thick and "airy", almost like cake frosting, and when you mix them together the volume doesn't increase, the paint just gets more dense.) None of the individual colors are gray; the only way to get gray is by mixing exactly three distinct colors, but it doesn't matter which three. Your friend Emily is an elementary school teacher and every Friday she does a fingerpainting project with her class. Given the number of different colors needed, the amount of each color, and the amount of gray, your job is to calculate the number of kits needed for her class.

      Input ;The input consists of one or more test cases, followed by a line containing only zero that signals the end of the input. Each test case consists of a single line of five or more integers, which are separated by a space. The first integer N is the number of different colors (3 <= N <= 12). Following that are N different nonnegative integers, each at most 1,000, that specify the amount of each color needed. Last is a nonnegative integer G <= 1,000 that specifies the amount of gray needed. All quantities are in ml.

      Output : For each test case, output the smallest number of fingerpainting kits sufficient to provide the required amounts of all the colors and gray. Note that all grays are considered equal, so in order to find the minimum number of kits for a test case you may need to make grays using different combinations of three distinct colors.

    examples : input

    3 40 95 21 0
    7 25 60 400 250 0 60 0 500
    4 90 95 75 95 10
    4 90 95 75 95 11
    5 0 0 0 0 0 333
    0

    output

    2
    8
    2
    3
    

     上面是全英文的描述, 当然如果看起来很费劲的话,我就用中文简单翻题意 : 玩具店有卖颜料的,一套是3到12种颜色,每一种颜色都有50ml,但是就是没有灰色的,灰色需要三种颜料来混合搅拌,这三种颜料都是Xml的就可以混合出Xml的灰色,现在,Emily要去店里面买颜料,最少要买多少套才能满足她的需求,输入的第一个数字是需要的普通的颜料种数,后面紧跟着的是需要的普通颜料的量,最后一个数字是需要的灰色的颜料的量,输出的就是需要买的颜料的套数

    思路 : 肯定先要对普通颜料做一个判断,以最大的量的那一个颜料来作为最低需要颜料套数的标准,注意这里如果最大的量不能整除50就得取上整数了,然后再考虑灰色的量,这时候就需要贪心算法的思想了,在满足了普通颜料的需求后,还剩下的量先由大到小排序,前三个来满足灰色的量直到,最后第三个的量用完了就继续加量,但是这里也有点鸡肋的是,每次只能1ml的来满足,而且每次完成后,都需要再次排个序,这样才能保证前三个永远是剩余最大量的颜料来供给灰色

    上代码

    package thinking;
    
    
    import java.util.Arrays;  
    import java.util.Collections;
    import java.util.Scanner;
    
    /*
     * This is the peking university's 2709 :
     * Description :  The local toy store sells small fingerpainting kits with between three and twelve 50ml bottles of paint, each a different color. 
     *     The paints are bright and fun to work with, and have the useful property that if you mix X ml each of any three different colors, 
     *     you get X ml of gray. (The paints are thick and "airy", almost like cake frosting, and when you mix them together the volume doesn't increase, the paint just gets more dense.)
     *  None of the individual colors are gray; the only way to get gray is by mixing exactly three distinct colors, but it doesn't matter which three.
     *   Your friend Emily is an elementary school teacher and every Friday she does a fingerpainting project with her class. 
     *   Given the number of different colors needed, the amount of each color, and the amount of gray, 
     *   your job is to calculate the number of kits needed for her class.
     * */
    
    /*
     * example : input : 3 40 95 21 0
                         7 25 60 400 250 0 60 0 500
                         4 90 95 75 95 10
                         4 90 95 75 95 11
                         5 0 0 0 0 0 333
                         0
                output : 2
                         8
                         2
                         3
                         4
     
    */
    
    
    public class Painter {
        // 为排序专门做一个函数,简化代码
        public void DescendingOrder(int[] arr, int size){ // 排序的算法是可以变的
            for(int i = 0; i<size-1; ++i){
                for(int j=i+1; j<size; ++j){
                    if(arr[i] < arr[j]){
                        int temp = arr[i];
                        arr[i] = arr[j];
                        arr[j] = temp;
                    }
                }
            }
        }
        public static void main(String[] args) {
            Painter painter = new Painter();
            System.out.println("你需要多少种颜料");
            Scanner in = new Scanner(System.in);
            int painterNum = in.nextInt();
            int[] painterKit = new int[painterNum];
            // 输入需要颜料的多少
            for(int i=0; i<painterNum; ++i){
                painterKit[i] = in.nextInt();
            }
            System.out.println("你需要的灰色是多少");
            int grayKit = in.nextInt();
            
            // 测试一下是否是输入了
            for (int kit : painterKit) {
                System.out.println(kit);
            }
            
            int count = 0; // 初始化需要买多少套颜料
            // 现在给需要的普通颜料进行一个排序,我先用一个冒泡试试看
            for(int i=0; i<painterNum-1; ++i){
                for(int j = i+1; j<painterNum; ++j){
                    if(painterKit[i] > painterKit[j]){ // 由小到大
                        int temp = painterKit[i];
                        painterKit[i] = painterKit[j];
                        painterKit[j] = temp;
                    }
                }
            }
            // 得到最大的量来算最低的需要的套数
            //System.out.println("test max : "+painterKit[painterNum-1]);
            count = painterKit[painterNum-1]/50; //最低需要的套数 , 这里还需要优化一下,会出现不是整数的情况
            if(painterKit[painterNum-1] % 50 != 0){
                count++;
            }
            // 下面就是满足普通颜料的需求之后还剩多少
            int[] painterKitLeft = new int[painterNum];
            for(int i=0; i<painterNum; ++i){
                painterKitLeft[i] = count*50 - painterKit[i]; 
            }
            // 测试一下是不是用完普通的还剩下相应的
    //        for(int i =0; i<painterNum; ++i){
    //            System.out.println(painterKitLeft[i]); // 是由大到小的,后面就是要体现贪心的算法了,虽然不是很明显
    //        }
            
            // 然后让剩下的来凑足灰色的颜料
            
            while(grayKit > 0){
                // 每次循环都要排序一次由小到大
                painter.DescendingOrder(painterKitLeft, painterNum);
                // 注意这里是从最大的量开始1ml开始减少,直到最后gray的量变成了0
                if(painterKitLeft[2] > 0){
                    grayKit --;
                    painterKitLeft[0] --;
                    painterKitLeft[1] --;                                            
                    painterKitLeft[2] --;
                }else{ // 知道前三中最少的
                    count ++;
                    for(int i=0; i<painterNum; ++i){
                        painterKitLeft[i] += 50;
                    }
                }
            }
            System.out.println("count :" +count);
        }
    }

    总结一下,这里的贪心算法又比最开始的贪心算法不同一点的是,以前的贪心算法,比较排序的因子只有一个,而这里的排序的因素是需要三个加起来的成为一个因子然后再来排序,并且这里面
    还会涉及到很多的处理...
  • 相关阅读:
    OCP-1Z0-053-V13.02-702题
    OCP-1Z0-053-V13.02-688题
    OCP-1Z0-053-V13.02-691题
    OCP-1Z0-053-V13.02-698题
    OCP-1Z0-053-V13.02-703题
    OCP-1Z0-053-V13.02-701题
    OCP-1Z0-053-V13.02-685题
    memcached 按键查找和批量查找
    catch(CException *e)捕获异常
    char数组最大长度
  • 原文地址:https://www.cnblogs.com/AmoryWang-JavaSunny/p/6534130.html
Copyright © 2011-2022 走看看