昨天模拟赛的时候坑了好久,刚开始感觉是dp,仔细一看数据范围太大。
题目大意:一个人要参加考试,一共有n个科目,每个科目都有一个相应的队列,完成这门科目的总时间为a+b*(前面已完成科目所花的总时间)。问:怎样安排考试的顺序使考完所花的总时间最短。
分析:假设已经花了time时间,在剩下的科目中任意取两个科目x,y。
先考试x:Tx=time+(ay*time+ax+bx*by*(ax+time));
先考试y:Ty=time+(by*time+bx+ax+ay*(bx+time))。
化简之后发现花费时间的差距在ax*by,ay*bx,那么按照ai/bi的大小进行排序就ok了。
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 5 #define N 100010 6 #define INF 0xffffffff 7 #define MOD (365*24*60*60) 8 9 struct node 10 { 11 __int64 a, b; 12 double s; 13 }; 14 node stu[N]; 15 16 int cmp (const void *a, const void *b) 17 { 18 node *c = (node *)a; 19 node *d = (node *)b; 20 21 return c->s > d->s ? 1:-1; 22 } 23 24 int main () 25 { 26 __int64 n, i, sum; 27 28 while (scanf ("%I64d", &n), n) 29 { 30 for (i=0; i<n; i++) 31 { 32 scanf ("%I64d %I64d", &stu[i].a, &stu[i].b); 33 if (!stu[i].a) 34 stu[i].s = 0; 35 else if (!stu[i].b) 36 stu[i].s = INF; 37 else 38 stu[i].s = 1.0 * stu[i].a / stu[i].b; 39 } 40 41 qsort (stu, n, sizeof(stu[0]), cmp); 42 sum = 0; 43 44 for (i=0; i<n; i++) 45 { 46 sum += (stu[i].a + stu[i].b * sum) % MOD; 47 sum %= MOD; 48 } 49 50 printf ("%I64d ", sum); 51 } 52 53 return 0; 54 }