POJ-3262 贪心的一个小技巧

Protecting the Flowers
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 3204   Accepted: 1300

Description

Farmer John went to cut some wood and left N (2 ≤ N ≤ 100,000) cows eating the grass, as usual. When he returned, he found to his horror that the cluster of cows was in his garden eating his beautiful flowers. Wanting to minimize the subsequent damage, FJ decided to take immediate action and transport each cow back to its own barn.

Each cow i is at a location that is Ti minutes (1 ≤ Ti ≤ 2,000,000) away from its own barn. Furthermore, while waiting for transport, she destroys Di (1 ≤ Di ≤ 100) flowers per minute. No matter how hard he tries, FJ can only transport one cow at a time back to her barn. Moving cow i to its barn requires 2 × Ti minutes (Ti to get there and Ti to return). FJ starts at the flower patch, transports the cow to its barn, and then walks back to the flowers, taking no extra time to get to the next cow that needs transport.

Write a program to determine the order in which FJ should pick up the cows so that the total number of flowers destroyed is minimized.

Input

Line 1: A single integer N 
Lines 2..N+1: Each line contains two space-separated integers, Ti and Di, that describe a single cow's characteristics

Output

Line 1: A single integer that is the minimum number of destroyed flowers

Sample Input

6
3 1
2 5
2 3
3 2
4 1
1 6

Sample Output

86

Hint

FJ returns the cows in the following order: 6, 2, 3, 4, 1, 5. While he is transporting cow 6 to the barn, the others destroy 24 flowers; next he will take cow 2, losing 28 more of his beautiful flora. For the cows 3, 4, 1 he loses 16, 12, and 6 flowers respectively. When he picks cow 5 there are no more cows damaging the flowers, so the loss for that cow is zero. The total flowers lost this way is 24 + 28 + 16 + 12 + 6 = 86.

Source

 
 
 
 
非常典型的贪心题,做起来也非常容易,很快就敲完了,主要卡我的地方在TLE。
是应该现在开始考虑一些这样的事了,N的范围为10的5次方,我第一次写的代码居然还用循环嵌套,这明显是TLE的命嘛。
其实一个小技巧完全可以避免双重循环,我居然没想到!!!!
嵌套的循环主要是在用来计算每头牛牵走后的剩余牛的破坏力,我居然模拟牵走过程,走掉一个牛,再模拟加一次破坏力。。很明显笨死了
 
明显每次计算的都是剩余牛的总破坏力,。。所以读数据的时候就顺便就把总破坏力存起来,。每走一头牛,就剪掉它对应的破坏力,这不就行了,一层循环搞定啊
 
其实不止是这个题目,这种小技巧其实跳出题目本身发现很简单,只是被题目的思维框住了,老想着去模拟一遍牵牛的过程。而且如果不是TLE的话,我还没发现这里有个优化方法。。。以后要尽量用这些优化方法来解题。
 
(我在TLE之后检查的时候,发现不仅数据量很大,数据本身可以累加到很大,所以把int 换成了__int64,..看discuss也发现确实要用64位。。之前都没意识到,还是太嫩了)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#define maxn 100005
using namespace std;
struct cow{
    int time;
    int des;
}node[maxn];
bool cmp(cow a,cow b)
{
    double t1=a.des*1.0/(a.time*1.0);
    double t2=b.des*1.0/(b.time*1.0);
    if (t1>t2)
    return true;

    return  false;
}
int main()
{
    int n;
    while (scanf("%d",&n)!=EOF)
    {
        __int64 now=0;
        for (int i=0;i<n;i++)
        {
            scanf("%d %d",&node[i].time,&node[i].des);
            now+=node[i].des;
        }
        sort(node,node+n,cmp);
        __int64 ans=0;
        //cout<<endl;
        for (int j=0;j<n-1;j++)
        {
            now-=node[j].des;
            ans+=now*node[j].time*2;
               // cout<<node[j].time<<" "<<node[k].des<<endl;
           // cout<<ans<<endl<<endl;
        }

        printf("%I64d\n",ans);
    }
    return 0;
}

 

posted @ 2013-07-23 16:25  KRisen  阅读(777)  评论(0编辑  收藏  举报