POJ3262 Protecting the Flowers
题目链接:
POJ3262 Protecting the Flowers
简单理解一下题目:
张三的奶牛本来在吃草,突然都跑去踩花了,张三只能把奶牛送回谷仓,但是他一次只能运送一头奶牛,运送这头奶牛的时候其他剩下的奶牛还在以各自的速度踩花,我们要找出一个运奶牛的方案使得踩花的损失最小,并输出最小损失花的数量。
简单分析:
这是个典型的贪心算法题,因为相当于是从从一群牛中挑选出最优解,挑选完之后的也是继续挑选最优解,要计算这个顺序,就要按照每个奶牛被选中时其余奶牛的破坏力来进行排序。假设是比较两头牛,分别为ta,da,tb,db,奶牛 a 被带回去时奶牛 b 的踩花数是ta*db,奶牛b被带回去时奶牛 a 的踩花数是tb*da,那么要比较这两者的大小,二者同时除以da*db,得到 ta/da 以及 tb/db ,这说明,我们只需要计算每头奶牛的 t/d ,按照这个从大到小进行排序,然后依次送回,所产生的损失就最小。
AC代码:
#include<iostream>
#include<algorithm>
using namespace std;
const int MAX_N = 100000;
int N;
long long result = 0;
struct node {
int t, d;
double temp;
}cows[MAX_N];
bool cmp(node a, node b)
{
return a.temp < b.temp;//排序方式
}
void solve()
{
sort(cows, cows + N, cmp);//按照temp=t/d从大到小排序
long long sum = 0;
for (int i = 0; i < N; i++)//计算出所有奶牛破坏花朵数量的总和
{
sum += cows[i].d;
}
for (int i = 0; i < N; i++)
{
sum -= cows[i].d;//这头牛被运回去的过程中不会继续破坏,所以直接减去
result += sum * cows[i].t * 2;//累积剩余奶牛在前面奶牛被送回去的时间里总共破坏的花朵数量
}
cout << result << endl;
}
int main()
{
cin >> N;
for (int i = 0; i < N; i++)
{
cin >> cows[i].t >> cows[i].d;
cows[i].temp = (1.0 * cows[i].t) / (1.0 * cows[i].d);//计算出每头奶牛的t/d用于排序,注意加上1.0,因为temp应该是浮点数
}
solve();
return 0;
}
/*
6
3 1
2 5
2 3
3 2
4 1
1 6
*/
做题心得:
这个题只要想明白t/d就比较好做,另外需要注意输出的result可能很大,要用long long,不然会WA。还有注意t/d应该用浮点数存储,运算的时候加上用1.0相乘转化一下。