题目:POJ - 3262

这道题,需要好好总结。

原来的思路是,依次计算出送走奶牛1~N会毁掉的花的数量,找出最小的,送走这头牛。然后又在剩下的奶牛中找可以使毁掉的花的数量最小的送走。如此循环直到全被送走。

对是对,只是也太繁琐了些,并且超时。

没有意识到其实这样的思路进行了很多次重复的比较。

 

后来看了别人的思路,发现可以先排序,一次就可以排好奶牛应该被送走的顺序。

刚开始觉得,这样很像之前做的Yogurt Factory题目,用动态规划记录每相邻两个牛的比较结果。

写完后发现不对,才发现又陷入了一个误区:动态规划适合于,前面的结果会影响后面的结果,但后面的不会影响前面的结果,的情况。

比如酸奶厂那道题,以后的星期可以用前一个星期生产的成本更低的酸奶,但之前的星期是不可用以后生产的,也就是说是局部比较,并不是统一的排序。

而这道题,需要统一的排序,因此只比较相邻两个是不行的。

 

刚开始想到了排序,但没有想到好的排序思路,觉得时长也不能作为依据,吃花数量也不能作为依据,没有想到这两个可以通过运算组成新的依据。

 

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <algorithm>
 4 
 5 using namespace std;
 6 
 7 int n;
 8 struct Cow {
 9     int first;
10     int second;
11     bool operator < (const Cow & c) {
12         return first * c.second < second * c.first;
13     }
14 }; 
15 Cow cow[100000];
16 typedef long long ll;
17 
18 int main() {
19     scanf("%d", &n);
20     ll sum = 0;
21     ll res = 0;
22     for (int i = 0; i < n; i++) {
23         scanf("%d %d", &cow[i].first, &cow[i].second);
24         sum += cow[i].second;   //sum记录所有奶牛吃花的总速度 
25     }
26     sort(cow, cow + n);
27     for (int i = 0; i < n - 1; i++) {
28         sum -= cow[i].second;   //每送走一头牛,吃花总速度就减去这头牛的速度 
29         res += 2 * sum * cow[i].first;      
30     } 
31     cout << res << endl;
32     return 0;
33 }

开始学习动态规划~