1. 程式人生 > >【題解】晚餐隊列安排

【題解】晚餐隊列安排

for 個數 當前 clu == 完全 是個 每天 輸入

題目描述

為了避免餐廳過分擁擠,FJ要求奶牛們分2批就餐。每天晚飯前,奶牛們都會在餐廳前排隊入內,按FJ的設想,所有第2批就餐的奶牛排在隊尾,隊伍的前半部分則由設定為第1批就餐的奶牛占據。由於奶牛們不理解FJ的安排,晚飯前的排隊成了一個大麻煩。

第i頭奶牛有一張標明她用餐批次D_i(1≤D_i≤2)的卡片。雖然所有N(1≤N≤30000)頭奶牛排成了很整齊的隊伍,但誰都看得出來,卡片上的號碼是完全雜亂無章的。

在若幹次混亂的重新排隊後,FJ找到了一種簡單些的方法:奶牛們不動,他沿著隊伍從頭到尾走一遍,把那些他認為排錯隊的奶牛卡片上的編號改掉,最終得到一個他想要的每個組中的奶牛都站在一起的隊列,例如112222或111122。有的時候,FJ會把整個隊列弄得只有1組奶牛(比方說,1111或222)。

你也曉得,FJ是個很懶的人。他想知道,如果他想達到目的,那麽他最少得改多少頭奶牛卡片上的編號。所有奶牛在FJ改卡片編號的時候,都不會挪位置。

輸入輸出格式

輸入格式

第一行,一個整數N。

第二至第N+1行,第i+1行是一個整數,為第i頭奶牛的用餐批次D_i。

輸出格式

一行,輸出一個整數,為FJ最少要改幾頭奶牛卡片上的編號,才能讓編號變成他設想中的樣子。

輸入輸出樣例

輸入樣例

7

2

1

1

1

2

2

1

輸出樣例

2

題解

雖然這題可以很輕松地用dp做出來,但是還是打算介紹一種前綴和的做法。

只需要用前綴和統計到當前的數字1或2的出現次數,然後枚舉最後有幾個數字1,利用前面的前綴和來算更改次數,取最優值即可。

技術分享圖片
#include<iostream>
using namespace std;
int n,temp,na[30005],nb[30005],mina=30005;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>temp;
        if(temp==1) na[i]++;
        else nb[i]++;
        na[i]
+=na[i-1]; nb[i]+=nb[i-1]; } for(int i=1;i<=n+1;i++) { if(na[n]-na[i-1]+nb[i-1]<mina) mina=na[n]-na[i-1]+nb[i-1]; } cout<<mina; return 0; }
參考程序

【題解】晚餐隊列安排