bzoj1634护花

mac2022-06-30  73

试题描述:

约翰留下他的N(N<=100000)只奶牛上山采木.他离开的时候,她们像往常一样悠闲地在草场里吃草.可是,当他回来的时候,他看到了一幕惨剧:牛们正躲在他的花园里,啃食着他心爱的美丽花朵!为了使接下来花朵的损失最小,约翰赶紧采取行动,把牛们送回牛棚. 牛们从1到N编号.第i只牛所在的位置距离牛棚Ti(1≤Ti≤2000000)分钟的路程,而在约翰开始送她回牛棚之前,她每分钟会啃食Di(1≤Di≤100)朵鲜花.无论多么努力,约翰一次只能送一只牛回棚.而运送第第i只牛事实上需要2Ti分钟,因为来回都需要时间.    写一个程序来决定约翰运送奶牛的顺序,使最终被吞食的花朵数量最小.

输入:

第1行输入N,之后N行每行输入两个整数Ti和Di

输出:

一个整数,表示最小数量的花朵被吞食

输入示例:

63 12 52 33 24 11 6

输出示例:

86

样例解释:

约翰用6,2,3,4,1,5的顺序来运送他的奶牛 

解题思路:

我开始蒙按D从大到小排,一样的按T从小到大拍,结果只过了3个点(还过了三个点?!)然后打算好好地堆贪心公式。

我们来看i和i+1这两头牛。

Ti     Ti+1

Di    Di+1

如果i在前面,那么这两头牛所耗费的价值是2Ti*Di+1,如果i+1,则价值为2Ti+1*Di只要看这两个值哪个大,就把哪个排前面。

贪心公式出来了

#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cmath> using namespace std; long long sum[100010]; long long n; long long ans = 0; struct node { long long t, d; int index; }input[100010]; bool cnp(node a,node b) { return a.t*b.d<a.d*b.t;//贪心公式 } int main() { freopen("flower.in", "r", stdin); freopen("flower.out", "w", stdout); cin >> n; for (int i = 1; i <= n; i++) { cin >> input[i].t >> input[i].d; input[i].index = i; } sort(input + 1, input + n + 1, cnp); for (int i = n; i >= 1; i--) sum[i] = sum[i + 1] + input[i].d; for (int i = 1; i <= n; i++) { int k = input[i].t * 2; ans += k*sum[i + 1]; } cout << ans; }

 

转载于:https://www.cnblogs.com/jason2003/p/7373825.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)