cf题目: Monsters And Spells

Monsters And Spells

题目链接

题目意思

一个战士打怪兽,每个怪兽有消失时间和血量,战士每秒可以蓄力1点,战士需要蓄力到大于等于该怪兽的血量才能消灭该怪兽,战士在每一秒可以选择继续蓄力或者是从头开始,从头开始的话,战士的的力量是1。
这道题目的思路就是从后面往前找,因为题目中给的数据是已经排好序的,所以最后面的肯定就是相对在时间轴的最右边的。我们思考下面的一个例子来引出思路:

2
5 7
5 6

可以看出 5 5 5 7 7 7之间隔了一个 6 6 6,而 7 7 7这边的怪兽血量是6,因此我们考虑最少花费情况的话, 5 5 5这里的战士能量应该是4,但是 5 5 5这边有一个怪兽血量是5(怪兽血量比我们期望的能量值大),因此我们只能让后面 7 7 7这边也加上1,这样才能保证在 5 5 5的时候战士能够有5能量值。
上面是怪兽血量比期望的能量值大的情况,那碰到小的情况就更好做了,我们就当这里能量值就是期望值就可以了,因为这样也可以把怪兽杀死。如果在这一点的期望值是0,那说明后面的已经对这一点再往前的点没有什么影响了,我们重新开始这一过程知道第一个怪兽即可。

代码如下

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e2+5;
ll a[maxn],h[maxn];
vector<pair<ll,ll> > record;

ll max(ll aa,ll bb)
{
    return aa>bb?aa:bb;
}

void solve()
{
    while(!record.empty())
    {
        record.clear();
    }
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%lld",&a[i]);
    for(int i=0;i<n;i++) scanf("%lld",&h[i]);
    int i=n-1;
    ll la=0,qi=0;
    ll now=i,nowc=h[i];
    i--;
    while(i>=0)
    {
        la=a[now]-a[i],qi=max(0,h[now]-la);//两者之间坐标差值,预期的能量值
        if(qi==0)
        {
            record.push_back(pair<ll,ll>(now,nowc));//vector数组相当于每次记录的是一轮中最后面那个点的时间坐标和在这一点的能量值
            now=i,nowc=h[i];
        }
        else if(qi<h[i])
        {
            nowc+=(h[i]-qi);//因为期望比实际的要小,所以我们更新这个值
            h[now]=nowc;//这里要更新h数组的值因为下一次循环的时候还要用到这个值
        }
        i--;
    }
    record.push_back(pair<ll,ll>(now,nowc));
    ll res=0;
    vector<pair<ll,ll> >::iterator it;
    for(it=record.begin();it!=record.end();it++)
    {
        res+=((it->second*(it->second+1))/2);//计算的时候因为是从1加到了这个值,因此直接计算等差数列前n项和
    }
    printf("%lld\n",res);
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        solve();
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值