codeforces-1334C-Circle of Monsters

传送门:https://codeforces.com/contest/1334/problem/C

题意:有一个游戏,n个怪物围成一圈,每个怪物有血量和爆炸后的伤害,每次你可以通过用枪打怪物使他们掉一滴血,每个怪物死亡后会对下一个怪物造成伤害,问最少打多少枪所有的怪物才能死

这个题,因为每个怪物都会死,所以每个怪物都会爆炸一回,那我们能尽量让所有怪物都承受一次前一个怪物爆炸的伤害才有可能是最优的,所以最优的情况就是引爆一个,然后他炸下一个,如果没炸死就补枪,所以现在问题就变成了,求引爆的最小枪数,不过,考虑一下,如果这个被引爆的怪物的血量比他的上一个怪物的伤害小,在计算补枪时没有影响,找a[i]最小值,但是如果这个被引爆的怪物的血量比他的上一个怪物的伤害大,那么会算上他被补枪的枪数,但是他已经死了,要把它减掉,就是a[i]-(a[i]-b[i-1])=b[i-1] 

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
ll a[300009],b[300009],di[300009];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        ll minn=1e14;
        for(int i=1;i<=n;i++) scanf("%lld%lld",&a[i],&b[i]);
        b[0]=b[n];
        for(int i=1;i<=n;i++)
        {
            if(a[i]<minn&&a[i]<=b[i-1]) minn=a[i];
            if(b[i-1]<minn&&a[i]>b[i-1]) minn=b[i-1];
            if(i!=1)  di[i]=(a[i]-b[i-1])>0?(a[i]-b[i-1]):0;
        }
        di[1]=(a[1]-b[n])>0?(a[1]-b[n]):0;
        ll ans=0;
        for(int i=1;i<=n;i++) ans+=di[i];
        ans+=minn;
        printf("%lld
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/YangKun-/p/12683716.html