1. 程式人生 > >FOJ Problem 2253 Salty Fish

FOJ Problem 2253 Salty Fish

註意 esc out pan 現在 區間 scrip ret eof

Problem 2253 Salty Fish

Accept: 35 Submit: 121
Time Limit: 1000 mSec Memory Limit : 32768 KB

Problem Description

海邊躺著一排鹹魚,一些有夢想的鹹魚成功翻身(然而沒有什麽卵用),一些則是繼續當鹹魚。一個善良的漁夫想要幫這些鹹魚翻身,但是漁夫比較懶,所以只會從某只鹹魚開始,往一個方向,一只只鹹魚翻過去,翻轉若幹只後就轉身離去,深藏功與名。更準確地說,漁夫會選擇一個區間[L,R],改變區間內所有鹹魚的狀態,至少翻轉一只鹹魚。

漁夫離開後想知道如果他采取最優策略,最多有多少只鹹魚成功翻身,但是鹹魚大概有十萬條,所以這個問題就交給你了!

Input

包含多組測試數據。

每組測試數據的第一行為正整數n,表示鹹魚的數量。

第二行為長n的01串,0表示沒有翻身,1表示成功翻身。

n≤100000

Output

在漁夫的操作後,成功翻身鹹魚(即1)的最大數量。

Sample Input

5 1 0 0 1 0 3 0 1 0

Sample Output

4 2

Hint

對於第一個樣例,翻轉區間[2,3],序列變為1 1 1 1 0。

對於第二個樣例,翻轉整個區間,序列變為1 0 1。

思路:最大連續子區間和問題,考慮兩部分,第一:記錄好原本的序列中1的個數sum1 第二:現在要反轉一個區間,此時對原串修改,0的部分改成1,1的部分改成-1,因為每次反轉,原本沒翻身的魚翻身了,則翻身的魚個數+1,而原本翻身的魚又變回鹹魚,翻身魚個數-1,對修改後的串求最大連續子區間和sum2,sum1+sum2即是最優解。當然本題需要註意如果所有魚本來都是1的狀態,則至少需要翻轉一條,最佳方案則為n-1.

AC代碼:

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<set>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
const int N_MAX = 100000+50;
int fish[N_MAX],a[N_MAX];
int n;
int main() {
    while (scanf("%d",&n)!=EOF) {
        int sum = 0
; for (int i = 0; i < n;i++) { scanf("%d",&fish[i]); if (fish[i]) { sum += fish[i], a[i] = -1; } else a[i] = 1; } int sum2 = 0,max_sum=a[0]; for (int i = 0; i < n;i++) { if(sum2>0) sum2 += a[i]; else sum2 = a[i]; max_sum = max(max_sum, sum2); } printf("%d\n",max_sum+sum); } return 0; }

FOJ Problem 2253 Salty Fish