uva 10670 Work Reduction

原题:
Paperwork is beginning to pile up on your desk, and tensions at the workplace are starting to mount. Your boss has threatened to fire you if you don’t make any progress by the end of the day. You currently have N units of paperwork on your desk, and your boss demands that you have exactly M units of paperwork left by the end of the day.The only hope for you now is to hire help. There are various agencies which offer paperwork reduction
plans:
•For A they will reduce your paperwork by one unit.
•For B they will reduce your entire paperwork by half (rounding down when necessary).
Note that work can never be reduced to less than0.
Your task now is to produce a sorted table of agency names and their respective minimum costs to solve your workload problem.
Input
The first line of input consists of a single positive integer representing the number of cases to follow.
Each case begins with three positive integers separated by spaces:
N - your starting workload, M - your target workload, and L - the number of work reduction
agencies available to you, (1 ≤ M ≤ N ≤ 100000, 1 ≤ L ≤ 100).
The next L lines have the format ‘agency name:A,B’, where A and B are the rates as described above for the given agency.(0 ≤ A,B ≤ 10000). The length of the agency name will be between 1 and 16, and will consist only of capital letters. Agency names will be unique.
Output
For each test case, print ‘Case X’, with X being the case number, on a single line, followed by the
table of agency names and their respective minimum costs, sorted in non-decreasing order of minimum
costs. Sort job agencies with identical minimum costs in alphabetical order by agency name. For each
line of the table, print out the agency name, followed by a space, followed by the minimum required
cost for that agency to solve your problem.
Sample Input
2
100 5 3
A:1,10
B:2,5
C:3,1
1123 1122 5
B:50,300
A:1,1000
C:10,10
D:1,50
E:0,0
Sample Output
Case 1
C 7
B 22
A 37
Case 2
E 0
A 1
D 1
C 10
B 50
大意:
你有n份文件,现在要你找帮手帮你完成n-m份,一共有l个帮手,每个帮手帮你的干活有两种方式,一种是一次完成一份文件并收取一份的价格,另一种是一次帮你完成剩余文件的一半,并收取对应的价格。现在问你每个帮手花最少的钱去完成n-m份的价格是多少,输出的时候按每个帮手的花销从小到大输出。如果花销相同,那么按名字的大小输出。

#include <bits/stdc++.h>

using namespace std;
//fstream in,out;
struct agencies
{
    string name;
    int one;
    int half;
    int cost;
};
agencies ag[101];
int cmp(const agencies &a,const agencies &b)
{
    if(a.cost!=b.cost)
        return a.cost<b.cost;
    else
        return a.name<b.name;
}
int main()
{
    ios::sync_with_stdio(false);
    int Case;
    int n,m,l,k=0,pn,pm;
    cin>>Case;
    string s;
    stringstream ss;
    while(Case--)
    {
        cin>>n>>m>>l;
        for(int i=1;i<=l;++i)
        {
            ss.clear();
            cin>>s;
            pn=s.find(':',0);
            pm=s.find(',',0);
            ag[i].name=s.substr(0,pn);
            ss<<s.substr(pn+1,pm-pn-1);
            ss>>ag[i].one;
            ss.clear();
            ss<<s.substr(pm+1,s.size()-pm-1);
            ss>>ag[i].half;
            ag[i].cost=0;
        }
        for(int i=1;i<=l;i++)
        {
            int tmp=n;
            while(tmp>m)
            {
                int t=tmp%2 ? tmp/2+1:tmp/2;
                if(t*ag[i].one>ag[i].half&&tmp-t>=m)
                {
                    tmp-=t;
                    ag[i].cost+=ag[i].half;
                }
                else
                {
                    ag[i].cost+=(tmp-m)*ag[i].one;
                    tmp=m;
                }
            }
        }
        sort(ag+1,ag+1+l,cmp);
        cout<<"Case "<<++k<<endl;
        for(int i=1;i<=l;i++)
            cout<<ag[i].name<<" "<<ag[i].cost<<endl;
    }
    return 0;
}

解答:
首先输入输出要处理一下。接下来比较两个方案,如果采用减半的方案的价格,和一个一个完成文件,直到完成一半所消耗的价格。如果减半的方案划算,且减半后大于等于m,就减半。如果第一次不能减半,那么减少后文件采用减半的方式肯定不划算,所以剩下的文件就全用一份一份完成的方式即可。

你可能感兴趣的:(uva)