1. 程式人生 > 實用技巧 >CF1418C Mortal Kombat Tower(找規律)

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); } }