zoukankan      html  css  js  c++  java
  • POJ Problem 3040 Allowance 【贪心】

    Allowance
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 2932   Accepted: 1183

    Description

    As a reward for record milk production, Farmer John has decided to start paying Bessie the cow a small weekly allowance. FJ has a set of coins in N (1 <= N <= 20) different denominations, where each denomination of coin evenly divides the next-larger denomination (e.g., 1 cent coins, 5 cent coins, 10 cent coins, and 50 cent coins).Using the given set of coins, he would like to pay Bessie at least some given amount of money C (1 <= C <= 100,000,000) every week.Please help him ompute the maximum number of weeks he can pay Bessie.

    Input

    * Line 1: Two space-separated integers: N and C 

    * Lines 2..N+1: Each line corresponds to a denomination of coin and contains two integers: the value V (1 <= V <= 100,000,000) of the denomination, and the number of coins B (1 <= B <= 1,000,000) of this denomation in Farmer John's possession.

    Output

    * Line 1: A single integer that is the number of weeks Farmer John can pay Bessie at least C allowance

    Sample Input

    3 6
    10 1
    1 100
    5 120

    Sample Output

    111
    

    Hint

    INPUT DETAILS: 
    FJ would like to pay Bessie 6 cents per week. He has 100 1-cent coins,120 5-cent coins, and 1 10-cent coin. 

    OUTPUT DETAILS: 
    FJ can overpay Bessie with the one 10-cent coin for 1 week, then pay Bessie two 5-cent coins for 10 weeks and then pay Bessie one 1-cent coin and one 5-cent coin for 100 weeks.

    Source

    贪心思路:
        先将面值大于c发给Bessie的钱。
        每次从面值最大的开始,用need数组存放每个面值所需要的数目,并且该面值的使用总价值不大于c,
        要是不足用小于该面值的补, 但是不大于c。如果c不为零,从最小的面值开始加上,使得损失最小。
        如果还有剩余的,说明所剩的金额已经不足以支付下一个月的。
        每次使得损失最少,所以总的损失是最小的,所支付的周数最小。

    #include <cmath>
    #include <queue>
    #include <stack>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define MAX_N 105
    #define MAX(a, b)   ((a > b)? a: b)
    #define MIN(a, b)   ((a < b)? a: b)
    using namespace std;
    
    struct node {
        int val, num;
    }mon[MAX_N];
    bool cmp(node x, node y) {
        return x.val < y.val;
    }
    int need[MAX_N];
    void init() {
        for (int i = 0; i < MAX_N; i++) {
            need[i] = 0;
        }
    }
    int main () {
        int c, n, m;
        while (scanf("%d%d", &n, &c) != EOF) {
            int ans = 0;
            for (int i = 0; i < n; i++) {
                scanf("%d%d", &mon[i].val, &mon[i].num);
            }
            int m = -1;
            sort(mon, mon + n, cmp);
            for (int i = n - 1; i >= 0; i--) {
                if (mon[i].val >= c) {
                    ans += mon[i].num;
                }
                else {
                    m = i;
                    break;
                }
            }
            while (true) {
                init();
                int res = c;
                //先进行循环,从面值最大的开始求所需 各面值的数目。
                for (int i = m; i >= 0; i--) {
                    if (mon[i].num && res) {
                        int k = res/mon[i].val;
                        k = MIN(k, mon[i].num);
                        need[i] = k;
                        res -= k*mon[i].val;
                    }
                }
                //如果剩下的大于零,说明不能支付正好的金额,就从最小的面值选一张。
                if (res) {
                    for (int i = 0; i <= m; i++) {
                        if (mon[i].val >= res && mon[i].num > need[i]) {
                            res = 0;
                            need[i]++;
                            break;
                        }
                    }
                }
                //如果还有剩余,就结束。
                if(res) break;
                int week = 1e8;
                //找出可以支付的最小的周数
                for (int i = 0; i <= m; i++) {
                    if (need[i])
                     week = MIN(week, mon[i].num/need[i]);
                }
                ans += week;
                for (int i = 0; i <= m; i++) {
                    mon[i].num -= need[i]*week;
                }
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    /*
    5 1
    9 6
    9 1
    6 2
    4 0
    1 8
    34
    */
    


     

  • 相关阅读:
    【PAT】1020. Tree Traversals (25)
    Pongo建立信号基站-实际上还是考中位数
    从此不再惧怕URI编码:JavaScript及C# URI编码详解
    WebBrowser与IE的关系,如何设置WebBrowser工作在IE9模式下?
    命令行下开启与关闭windows防火墙关端口(转)
    MySql数据库批量备份命令
    C#检查文件是否被占用
    C#使用Gzip解压缩完整读取网页内容
    [转]免费电话网专用免费平台
    libQt5Core.so: undefined reference to `dlclose@GLIBC_2.4'
  • 原文地址:https://www.cnblogs.com/cniwoq/p/6770917.html
Copyright © 2011-2022 走看看