【Codeforces EC 85】 C. Circle of Monsters 思维 预处理

You are playing another computer game, and now you have to slay n monsters. These monsters are standing in a circle, numbered clockwise from 1 to n. Initially, the i-th monster has ai health.

You may shoot the monsters to kill them. Each shot requires exactly one bullet and decreases the health of the targeted monster by 1 (deals 1 damage to it). Furthermore, when the health of some monster i becomes 0 or less than 0, it dies and explodes, dealing bi damage to the next monster (monster i+1, if i

You have to calculate the minimum number of bullets you have to fire to kill all n monsters in the circle.

Input
The first line contains one integer T (1≤T≤150000) — the number of test cases.

Then the test cases follow, each test case begins with a line containing one integer n (1≤n≤300000) — the number of monsters. Then n lines follow, each containing two integers ai and bi (1≤ai,bi≤1012) — the parameters of the i-th monster in the circle.

It is guaranteed that the total number of monsters in all test cases does not exceed 300000.

Output
For each test case, print one integer — the minimum number of bullets you have to fire to kill all of the monsters.

Example
inputCopy
1
3
7 15
2 14
5 3
outputCopy
6

题意:有一个n个怪物,环形排列,每个怪物有a[i]滴血,每次射击可以-1滴血,死后爆炸产生b[i]伤害,能伤害到下一个怪物,若炸死了下一个,也是同样爆炸,问最小射击次数使得全部怪物GG

思路:

1.因为我每个怪物死后只会对下一个怪物产生影响,而且炸死了的怪物不用管,没炸死的就要补枪。
2.发现到在这个环形中,我们只用决定第一个射杀哪个怪物,剩下的要击杀的顺序其实已经固定了。比如 i 位置当作第一次射击对象,那么我下一次肯定不会选择i-1位置,为什么?因为i位置已经空了,i-1位置就算死了,也不会对其他产生影响,就浪费了一次爆炸。而i+1(或者最近的还存在怪兽)的位置又不会再有爆炸对他造成影响,所以它是必定要射击的。以此类推。
3.所以我们可以先求出数列的差分和(a[i]-b[i-1]),然后枚举第一个射击位置就行了。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define maxn 300000+500
using namespace std;
typedef long long ll;

ll a[maxn];
ll b[maxn];
ll c[maxn];
ll sum[maxn];
int main()
{
    int kase;
    cin>>kase;
    while(kase--)
    {
            ll n;
            scanf("%lld",&n);
            for(ll i=0;i<n;i++)
            {
                scanf("%lld%lld",&a[i],&b[i]);
            }
            ll sum = 0;
            for(ll i=0;i<n;i++)
            {
                 if(i==0) c[i] = max(0ll, a[0] -b[n-1] );
                 else c[i] = max(0ll,  a[i]-b[i-1]);
                 sum += c[i];
            }
            ll ans = 1e18;
            for(ll i=0;i<n;i++)
            {
                    ans = min(ans, sum-c[i] + a[i]);
            }
            printf("%lld\n",ans);
    }
    return 0;
}


你可能感兴趣的:(题解,codeforces)