H. Fight Against Monsters(贪心)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这个题题目的意思很好懂;就是有n个怪兽,他们各自的Hp和Atk都给了;然后一个英雄去kills这些Monsters;
但是有个规则:就是该英雄对一个怪物,他对怪物的伤害是随着攻击次数增加的;也就是等差数列(第一次为1点伤害,第二次为2点伤害,第三次为3点伤害…);但是在英雄攻击怪物之前他会被所有的怪物攻击;并且受到的损伤是所有怪物的攻击力之和;然后求kill所有怪物的情况下英雄的受伤值最小是多少;
其实这道题我刚开始被案例带偏了;我直接按照Atk排个序,然后求每个的攻击次数就完了(因为我觉得需要把Atk最大的先干掉);结果就是wa了;后来队友想了想;他举了一个例子:
在这里插入图片描述
右边的就是反例;如果只考虑把Atk高的先kill掉,那么右边的例子就是21;很明显这个有问题;因为答案为19;因为我可以先把2kill掉;所以我就不应该这样想了;后来发现这个问题;如果我把对英雄平均伤害大的先kill掉不就可以了吗?意思就是:
每个monster对应的Atk值/他被kill掉的次数;那么不就是平均每次对英雄造成伤害大的吗?所以直接求出这个比值,那后sort一下最后算一算次数就AC了;因为这个我还wa了两次,无语了QAQ;总得来说就是去找每次对英雄伤害比较大的怪物,然后kill它,只不过这个平均值还真的不好想;感觉有点像挑战设计上面的最大化平均值一样;所以就是(Atk/需要被干掉的次数)这个值排个序就AC了;

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Monster{
	 ll hp,ak;
	double Cmp;
}p[100050];
bool cmp(Monster a,Monster b){//这里用来排序,从大到小
	  return a.Cmp>b.Cmp;
}
int main(){
    ll T;
    cin>>T;
    	ll n;
    	ll ans,all;
    	ll g=1;
      while(T--){
    	ans=0;
    	all=0;
    	cin>>n;
    	for(ll i=0;i<n;i++){
		  cin>>p[i].hp>>p[i].ak;
		   all+=p[i].ak;
		}
    	for(ll i=0;i<n;i++){
             ll tt=ceil((-1+sqrt(1+8.0*p[i].hp))/2.0);//这里需要向上取整,因为如果hp为4,那么你算出来的n就是2.几,所以你需要3次kill这个怪物;这里是求根公式,求的是kill这个怪物的次数
			 p[i].Cmp=p[i].ak*1.0/tt;		//这里是求比值
    	} 
    	sort(p,p+n,cmp);
    	//for(int i=0;i<n;i++)cout<<p[i].Cmp<<" ";
         	for(ll i=0;i<n;i++){
             ll tt=ceil((-1+sqrt(1+8.0*p[i].hp))/2.0);
			 ans+=tt*all;
			 all-=p[i].ak;		  
        	} 
    	printf("Case #%lld: %lld\n",g++,ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值