| ||||||||||
| 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