10026 - Shoemaker's Problem(贪心)

来源:互联网 发布:美国原油库存eia数据 编辑:程序博客网 时间:2024/06/05 12:42

该题是说有n个任务,每个任务都有一个需要的时间,还有一个价格,这个价格的意思是:在开始处理该任务之前的每一天都亏损这个价格,问最小亏损的安排是什么样的。

YY了一下,发现样例是按照:价格/时间 进行了排序,其次按照编号排序。

大概的原理类似于性价比之类的吧,从样例就可以看出来,不一定要先处理价格高的就好,还有完成天数的限制。

至于这个贪心方法的证明,网上搜到一个:对于为什么贪心策略是这个样子的,我们不妨拿相邻的两个事件ab来说明一下。由于ab之后的事件是固定的,所以我们无论排成ab还是排成ba后面部分的损失都是固定的,那么损失的差别主要来源于究竟是排成ab还是排ba。排ab的损失为ta*fb,排ba的损失为tb*fa,那么如果ta*fb<tb*fa,我们就排成ab,这样可以得到fa/ta>fb/tb,推而广之,就得到了我们的贪心策略。

细节参见代码:

#include<bits/stdc++.h>using namespace std;typedef long long ll;const double eps = 1e-6;const int maxn = 1000;int T,n,m;struct node{    double t,v,cc;    int id;    bool operator < (const node& rhs) const {        if(fabs(cc - rhs.cc)>eps) return cc > rhs.cc;        else return id < rhs.id;    }}a[maxn];int main() {    scanf("%d",&T);    while(T--) {        scanf("%d",&n);        for(int i=0;i<n;i++) {            scanf("%lf%lf",&a[i].t,&a[i].v);            a[i].id = i+1;            a[i].cc = a[i].v / a[i].t;        }        sort(a,a+n);        printf("%d",a[0].id);        for(int i=1;i<n;i++) printf(" %d",a[i].id);        printf("\n");        if(T) printf("\n");    }    return 0;}


0 0
原创粉丝点击