题意是你打dota,1 v N,给你对方的血量和DPS,让你采取最好的方案灭掉对方的所有英雄,并且自己受到的伤害最少。
开始的时候猜想是想杀DPS最高的,然后发觉血量也有影响且可以杀血量最少的,于是想到可以把DPS放在分子,把血量放在分母,然后类似性价比一样先杀性价比最高的。
然后学长给了这样做的证明:
假设两英雄,第一次的顺序是先杀英雄1(dps1,hp1),再杀英雄2(dps2,hp2);
第二次先杀英雄2,再杀英雄1;
则: 第一次损失的血量:dps1 * hp1 + dps2 * ( hp1 + hp2 )
第二次损失的血量:dps2 * hp2 + dps1 * ( hp1 + hp2 )
列出了两种情况以后,我们呢要比较大小,所以用损失血量一减去损失血量二,假设损失一大于损失二,就可以得出:
dps2 * hp1 - dps1 * hp2 > 0 ,移向,可得: dps2 / hp2 > dps1 / hp1 .
由假设,可知这个式子说明,先杀掉 dpsi / hpi 高的英雄,损失的血量少,得证。
一次ac很过瘾啊。
代码:
#include<stdio.h>
#include<algorithm>
using namespace std;
const int MaxN = 21;
struct Hero
{
float dps;
float hp;
float dh;
bool operator < (const Hero &b)const
{
return dh > b.dh;//从大到小排
}
}h[MaxN];
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif // LOCAL
int n;
while(scanf("%d", &n)!=EOF)
{
for(int i = 0; i < n; i++)
{
scanf("%f%f", &h[i].dps, &h[i].hp);//%f debug
h[i].dh = h[i].dps / h[i].hp;
}
sort(h , h + n);
/*for(int i = 0; i < n; i++)
{
printf("%f %f\n", h[i].dps, h[i].hp);
}*/
int sum = 0, ps = 0;
for(int i = 0; i < n; i++)
{
ps += h[i].hp;
sum += ps * h[i].dps;
}
printf("%d\n", sum);
}
return 0;
}