该题是说有n个任务,每个任务都有一个需要的时间,还有一个价格,这个价格的意思是:在开始处理该任务之前的每一天都亏损这个价格,问最小亏损的安排是什么样的。
YY了一下,发现样例是按照:价格/时间 进行了排序,其次按照编号排序。
大概的原理类似于性价比之类的吧,从样例就可以看出来,不一定要先处理价格高的就好,还有完成天数的限制。
至于这个贪心方法的证明,网上搜到一个:对于为什么贪心策略是这个样子的,我们不妨拿相邻的两个事件a、b来说明一下。由于a、b之后的事件是固定的,所以我们无论排成ab还是排成ba后面部分的损失都是固定的,那么损失的差别主要来源于究竟是排成ab还是排b成a。排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;
}