USACO培训:混合牛奶在最后一个案例中失败

时间:2016-02-18 22:51:10

标签: java algorithm arraylist hashmap greedy

这是混合牛奶问题

Merry Milk Makers公司从农民手中购买牛奶,将其装入有吸引力的1瓶和2瓶装瓶中,然后将这些牛奶卖给杂货店,这样我们就可以用美味的谷物和牛奶开始新的一天。

由于牛奶包装是一项难以赚钱的业务,因此保持尽可能低的成本非常重要。帮助Merry Milk Makers以最便宜的方式购买农民的牛奶。 MMM公司拥有一个非常有才华的营销部门,他们确切地知道他们每天需要多少牛奶来为他们的客户打包。

该公司与几个农民签订合同,他们可以从中购买牛奶,每个农民都有(可能)不同的价格,他们向包装厂出售牛奶。当然,一群奶牛每天只能生产这么多牛奶,所以农民们已经知道他们可以提供多少牛奶。

每天,Merry Milk Makers可以从每个农民手中购买一定数量的牛奶单位,这个数字总是小于或等于农民的限制(可能是该农民的整个生产,没有一个生产,或其间的任何整数)。

鉴于

Merry Milk Makers的每日牛奶需求量 每个农民的牛奶每单位成本 每个农民可获得的牛奶量 计算Merry Milk Makers必须花费的最低金额,以满足他们每天的牛奶需求。

第1行:两个整数,N和M.

第一个值N,(0 <= N <= 2,000,000)是Merry Milk Makers每天想要的牛奶量。 第二个,M,(0 <= M <= 5,000)是他们可以购买的农民数量。

第2行到第M + 1行:

接下来的M行每行包含两个整数:Pi和Ai。 Pi(0 <= Pi <= 1,000)是农民收费的分数。 Ai(0 <= Ai <= 2,000,000)是农民每天可以向Merry Milk Makers销售的牛奶量。

我的解决方案

我的解决方案是将农民的牛奶价格和牛奶的数量存储在HashMap。只要还有牛奶可以购买,我会将最低价格*从HashMap的最低牛奶价格加到成本中,因为我将ArrayList分类存储成本牛奶。因为购买的牛奶可能比需要的多,我有if statement检查如果购买的牛奶超过需要量,则会减去额外的费用。然后,我从ArrayList

中删除最低价格

代码

该代码适用于所有测试用例,但最后一个测试用例除外,其中有太多数据要放入问题中,因此我将其链接到Google文档。

输入和输出:https://docs.google.com/document/d/10I3b0z17kP_LZzD2lBlH-Igoe6NPybZleD9tNYonqSQ/edit?usp=sharing

/*
ID: henry.d2
LANG: JAVA
TASK: milk
*/

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class milk
{
    public static void main(String[] args) throws IOException
    {
        BufferedReader br = new BufferedReader(new FileReader("milk.in"));

        String[] components = br.readLine().split(" ");

        int n = Integer.parseInt(components[0]); // Get the amount of milk that Merry Milk Makers wants per day (N)
        int m = Integer.parseInt(components[1]); // Get the number of farmers that they may buy from (M)

        Map<Integer, Integer> farmerAndPrice = new HashMap<Integer, Integer>(); // HashMap that stores the prices of milk and quantities
        List<Integer> prices = new ArrayList<Integer>(); // ArrayList that stores the prices for milk

        // Read in P(i) (The price in cents that farmer i charges) and A(i) (The amount of milk that farmer i can send to MMM per day)
        for (int i = 0; i < m; i++)
        {
            String[] pAndA = br.readLine().split(" ");

            int Pi = Integer.parseInt(pAndA[0]);
            int Ai = Integer.parseInt(pAndA[1]);

            farmerAndPrice.put(Pi, Ai); // Add price and quantity to HashMap
            prices.add(Pi); // Add price to ArrayList
        }

        Collections.sort(prices);

        int milkToBuy = 0;
        int cost = 0;

        while (milkToBuy < n) // The farmers still have milk to buy from
        {
            cost += farmerAndPrice.get(prices.get(0)) * prices.get(0);
            milkToBuy += farmerAndPrice.get(prices.get(0));

            if (milkToBuy > n) // If we buy more milk than we need
            {
                cost -= (milkToBuy - n) * prices.get(0);
            }

            System.out.println(prices.toString());

            prices.remove(0);
        }

        File file = new File("milk.out"); // Output to milk.out
        PrintWriter printWriter = new PrintWriter(file);

        printWriter.println(cost);

        printWriter.close();
    }
}

2 个答案:

答案 0 :(得分:1)

我非常有信心你没有正确考虑当多个农民以相同的价格出售牛奶时会发生什么。

您使用哈希地图的方式意味着您将覆盖以前农民的价值观。

答案 1 :(得分:0)

另一种解决方案是将每个农民提供的牛奶量和单价存储在结构中,然后根据最低单价对结构进行分类。然后你可以循环遍历数组列表(直到所需的单位变为0)。

我不知道java代码是什么,但这里是我用来提交给USACO网站的c ++代码:

#include <iostream>
#include <fstream>

typedef struct _PandQ
{
    int milkAmount;
    int unitPrice;
}PandQ;

PandQ *sortInput(int nOfFarmers,PandQ arrUnitPrices[])
{
    for(int iCtr=1;iCtr<nOfFarmers;iCtr++)
    {
        for(int jCtr=0;jCtr<nOfFarmers-iCtr;jCtr++)
        {
            if(arrUnitPrices[jCtr].unitPrice>arrUnitPrices[jCtr+1].unitPrice)
            {
                swap(arrUnitPrices[jCtr],arrUnitPrices[jCtr+1]);
            }
        }
    }
    return arrUnitPrices;
}

int main()
{
    ofstream fout("milk.out");
    ifstream fin("milk.in");
    int reqUnits,nOfFarmers,leastPriceTally,totPrice=0,temp=0,remainder;
    int milkCtr=0;
    PandQ *arrUnitPrices;
    fin>>reqUnits>>nOfFarmers;

    arrUnitPrices=new PandQ[nOfFarmers];
    /*
        to take in values of prices of farmers' milk and amount each farmer has (from file).
    */
    for(int iCtr=0;iCtr<nOfFarmers;iCtr++)
    {
        fin>>arrUnitPrices[iCtr].unitPrice;
        fin>>arrUnitPrices[iCtr].milkAmount;
    }

    arrUnitPrices=sortInput(nOfFarmers,arrUnitPrices);

    while(reqUnits>0)
    {
        if(arrUnitPrices[milkCtr].milkAmount<reqUnits)
        {
            totPrice+=arrUnitPrices[milkCtr].milkAmount*arrUnitPrices[milkCtr].unitPrice;
            reqUnits-=arrUnitPrices[milkCtr].milkAmount;
        }
        else if(arrUnitPrices[milkCtr].milkAmount>=reqUnits)
        {
            totPrice+=reqUnits*arrUnitPrices[milkCtr].unitPrice;
            reqUnits=0;
        }
        milkCtr++;
    }
    fout<<totPrice<<"\n";
}