FOJ Problem 2253 Salty Fish
阿新 • • 發佈:2017-07-17
註意 esc out pan 現在 區間 scrip ret eof Problem 2253 Salty Fish
Accept: 35 Submit: 121
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 0Sample Output
4 2Hint
對於第一個樣例,翻轉區間[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