CF1418C Mortal Kombat Tower(找規律)


您和您的朋友正在玩游戲真人快打XI。您正在嘗試通過挑戰塔。該塔中有n個凸台,從1到n。第i個老板的類型是ai。如果第i個首領很容易,則其類型為ai = 0,否則,此首領為堅硬且其類型為ai = 1。

題意:

在一個會話中,您或您的朋友可以殺死一個或兩個老板(您和您的朋友都不能跳過該會話,因此在一個會話中被殺死的老板最少要有一個)。在您的朋友會話之后,您的會話開始,然后再次您的朋友會話開始,您的會話開始,依此類推。第一場是您朋友的一場。

您的朋友需要變得良好,因為他實際上無法殺死艱難的老板。為了殺死他們,他使用了跳過點。一個跳過點可以用來殺死一個堅強的上司。

您的任務是找到您的朋友需要使用的最小跳過點數,以便您和您的朋友按給定順序殺死所有n個頭目。

例如:假設n = 8,a = [1,0,1,1,0,1,1,1]。那么最好的做法是:

您的朋友殺死了兩個首領,對首個老板使用一個跳躍點;
您殺死了第三和第四位老板;
您的朋友殺死了第五任老板;
你殺死了第六和第七個boss;
您的朋友使用一個跳過點殺死了最后一個老板,因此使用兩個跳過點完成了塔。
您必須回答t個獨立的測試用例。

輸入項
輸入的第一行包含一個整數t(1≤t≤2⋅104)—測試用例的數量。然后是t個測試用例。

測試用例的第一行包含一個整數n(1≤n≤2⋅105)-凸台數。測試用例的第二行包含n個整數a1,a2,…,an(0≤ai≤1),其中ai是第i個首部的類型。

保證n的總和不超過2⋅105(∑n≤2⋅105)。

輸出量
對於每個測試用例,請打印答案:朋友需要使用的最小跳過點數,以便您和朋友按給定順序殺死所有n個頭目。

題解:

規律題,思考后可以發現,除了開頭為1的情況,任意一段連續為1的子序列,都能轉化為我先手,朋友后手的情況。依次枚舉算貢獻即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+100;
const int inf=1e9;
int n;
int t;
int a[maxn];
int main () {
    scanf("%d",&t);
    while (t--) {
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%d",a+i);
        a[n+1]=0;
        int ans=0;
        int tot=0;
        //貪心
        //把盡可能多的1留給我
        //對於一段連續是1的長度是k的區間
        //如果朋友先手, ans+=k/3+(k%3>0?1:0)
        //如果我先手,ans+=k/3
        int f=0;
        for (int i=1;i<=n;i++) {
            if (!a[i]) continue;
            int j;
            for (j=i;j<=n;j++) if (a[j]==0) break;
            int k=j-i;
            if (i>1) 
                ans+=k/3;
            else {
                ans+=k/3+(k%3>0?1:0);
                f++; 
            }
            i=j-1;
        }
        printf("%d\n",ans);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM