UVa:10670 Work Reduction

题意:老板给你n个文件,要求你最终正好剩下m个文件,你需要寻求l个机构帮助你完成其它文件。每个机构有两项服务:花费A完成一个文件;花费B完成一半文件。问你每个机构独立完成任务所需最小花费是多少。

思路:贪心。方法很好想,当完成一半时剩余量大于m的时候,考虑服务A跟B哪个花费少。如果A少,那么只需选择A直到剩余m完成任务即可。如果选择B,那么就完成一半任务,剩下的一半接着这样判断哪个更合适,直到某时选择了A或者一半小于m的时候此时只能选A。


注意如果相同要按字典序输出。

#include <cstdio>
#include <algorithm>
#include<cstring>
#include<iostream>
#include<cstdlib>
using namespace std;
struct Reduction
{
    string name;
    int A,B,ans;
    Reduction():A(0),B(0),ans(0) {}
};
bool cmp( Reduction a, Reduction b)
{
    if(a.ans==b.ans) return a.name<b.name;
    return a.ans<b.ans;
}
int main()
{
    int T,kase=0;;
    cin>>T;
    while(T--)
    {
        int n,l, m;
        cin>>n>>m>>l;
        Reduction p[105];
        string str;
        for(int i=0; i<l; ++i)
        {
            cin>>str;
            int sw=0;
            for(int j=0; j<str.size(); ++j)
            {
                if(str[j]!=':'&&!sw)
                    p[i].name+=str[j];
                if(str[j]==':')
                    sw=1;
                if(isdigit(str[j])&&sw==1)
                    p[i].A=p[i].A*10+(str[j]-'0');
                if(str[j]==',')
                    sw=2;
                if(isdigit(str[j])&&sw==2)
                    p[i].B=p[i].B*10+(str[j]-'0');
            }
            int res=n,ans=0;
            while(res*0.5>=m)
            {
                if(p[i].A*res*0.5<=p[i].B)
                {
                    ans+=(res-m)*p[i].A;
                    res=0;
                    break;
                }
                else
                {
                    ans+=p[i].B;
                    res=res*0.5;
                }
            }
            if(res>m)
                ans+=(res-m)*p[i].A;
            p[i].ans=ans;
        }
        sort(p,p+l,cmp);
        cout<<"Case "<<++kase<<endl;
        for(int i=0; i<l; ++i)
            cout<<p[i].name<<" "<<p[i].ans<<endl;
    }
    return 0;
}


你可能感兴趣的:(贪心)