Description
现有
n
个怪物,每个怪物有一个生命值
Solution
这题我们显然可以用搜索,动态规划等方法骗分。
但,这题看上去就是贪心。
对于20%数据(没有魔法值),我们考虑从小到大排序,逐个击毙。
扩展到100%的数据,若剩余怪物个数大于2,肯定是先放群攻。
现在来讨论一下剩余怪物个数等于2:那么我们先用重击把怪物打死或生命值减少到1,这时如果较小生命值的怪物生命值为1,我们肯定放群攻。
如果怪物只剩1只了,那么能重击就重击。
在操作过程中如果发现魔法值没有了,就一次次普通攻击即可。
Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define N 100001
#define ll long long
using namespace std;
int a[N];
int main()
{
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
int n,m;
cin>>n>>m;
fo(i,1,n) scanf("%d",&a[i]);
sort(a+1,a+n+1);
int t=n;
ll ans=0;
int q=0;
fo(i,1,n)
if(a[i]-q>0)
{
if(t>2)
{
while(m && a[i]-q)
{
m--,q++;
if(a[i]-q) ans+=t;
else
{
fo(j,i,n)
if(a[j]==a[j+1]) t--;
else break;
t--;
ans+=t;
}
}
}
if(!(a[i]-q)) continue;
if(t<=2 && a[i]-q>1 && m)
{
while(a[i]-q>1 && m)
{
m--;a[i]-=2;
if(!(a[i]-q)) t--;
ans+=t;
}
}
if(!(a[i]-q)) continue;
if(t==2 && a[i]-q==1 && m)
{
m--,q++;
fo(j,i,n)
if(a[i]==a[i+1]) t--;
else break;
t--;
ans+=t;
}
if(!(a[i]-q)) continue;
if(!m || a[i]-q==1)
{
ans=ans+(a[i]-q-1)*1ll*t;
t--;
ans+=t;
a[i]=0;
}
}
cout<<ans;
}