Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
并查集只是优化,普通方法也能过的贪心排完序后,从大插起,类似Hash表解决冲突一样,一旦要插入的时间已经有其他物品了,则 将要插入的物品的时间-1,即往前面一个时间插,如果又是已经有物品的,就继续-1,直到<1 了,说明他前面都插完了,就放弃该物品,继续后面的物品判断。由此可见Find的操作是O (1),Union-Insert的操作是O(n),如果用并查集,则Find的操作是O(logn),Union的操作是O (1).如果用压缩路径,则Find可以在第一次用O(logn)查找后,再花费O(logn)将路径上的结点 指针指向根,故以后路径上的节点的Find都是O(1),实际上并没有多好的优化。很多算法为了提 高一点效率,把算法写得复杂难懂甚至结果反而没有优化到,反而不是可取的,但是ACM有些题目 你还真得这么做。。。 typedef struct annal { int proft; int time; }Annal; Annal arr[10001]; int cmp(const void*a,const void*b) { Annal *c = (Annal*)a; Annal *d = (Annal*)b; return d->proft - c->proft; } int main() { int n,i,j; int s; int last; int temp[10001]; int maxtime; while(scanf("%d",&n)!=EOF) { s=0; last = -1; memset(temp,0,sizeof(temp)); for(i=0;i<n;i++) { scanf("%d %d",&arr[i].proft,&arr[i].time); if(i==0) maxtime = arr[0].time; else if(arr[i].time>maxtime) maxtime = arr[i].time; } qsort(arr,n,sizeof(arr[0]),cmp); for(i=0;i<n;i++) { if(arr[i].time<1) continue; if(temp[arr[i].time] == 0) temp[arr[i].time] = arr[i].proft; else arr[i].time--,i--; } for(i=1;i<=maxtime;i++) s+=temp[i]; printf("%d\n",s); } return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator