1. 程式人生 > >Gym - 101962K _ Rei do Cangaço

Gym - 101962K _ Rei do Cangaço

題意:給予n個房間,每個房間可以的到x個金幣(x可能為負數),可以進行兩種操作:

  • 右移3i個房間,並且開啟除最後一個的所有房間,如在1號房間,第一次移動可以移動到4號,並且開啟1,2,3三個房間。
  • 只右移3i個房間。

如果他走到最後一個房間,那麼本輪遊戲結束,求起點分別從1到n號房間開始最多能拿到多少金幣,(金幣數量不為負數)。
題意:i是第i次移動而不是第i個房間,這一點被坑到哭,一開始暴力將他這一次能開啟的房間獲得的金幣數全部加起來,如果為正就執行操作一,否則執行操作二,雖然能過,但是耗時有點長。其實可以把這個房間前所有房間獲得的金幣數加起來,a[i]-a[i-1]就是這個房間能獲得的金幣數量,如果這一次從i移動到j那麼a[j-1]-a[i-1]就是此次移動能獲得的金幣數量。

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

using namespace std;

int main()
{
    int a[500050],sum,i,j,k,q,n;
    scanf("%d",&n);
    a[0] = 0;
    for(i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        a[i] += a[i-1];
    }
    for(i=1;i<=n;i++)
    {
        q = 3;
        sum = 0;
        for(j=i;j<=n;j+=q,q+=3)
        {
            k = j + q - 1;
            //printf("\t%d\n",k);
            if(k>n)
                k = n;
            sum += max(0,a[k] - a[j-1]);
        }
        printf("%d\n",sum);
    }
    return 0;
}