Problem:
C - チョコレート

目の前に M \times N 個のピースでできた板チョコがある．
ピースには甘いピースと辛いピースの2種類があり，できるだけ多くの甘いピースを食べたい．

しかし，板チョコの食べ方にはルールがあり，以下のルールを守らなければならない．

あるピースを食べるためには，そのピースの真上に隣接するピースが存在せず，加えてそのピースの少なくとも左右どちらかにはピースが存在しない必要がある．

例えば，図のような形のチョコレートでは，赤く色付けされたピースを次に食べることができる．

また奇妙なことに，あるピースを食べるとそのピースの上下左右に隣接していてかつまだ食べられていないピースの味が変化する． (甘いピースは辛く，辛いピースは甘くなってしまう)

上手くチョコレートを食べると最大でいくつの甘いピースを食べることができるだろうか?

入力形式

入力は以下の形式で与えられる．

M N
a_{11} … a_{1N}
a_{21} … a_{2N}
:
a_{M1} … a_{MN}

a_{ij} = 0 のとき上からi番目，左からj番目のピースが辛く，
a_{ij} = 1 のとき上からi番目，左からj番目のピースが甘いことを表わしている．

出力形式

食べることのできる甘いピースの個数の最大値を一行に出力せよ．

制約

1 \leq N，M \leq 100

0 \leq a_{ij} \leq 1

入力値はすべて整数である．

入出力例

入力例1

2 3
1 1 1
1 1 1

出力例1

5

入力例2

4 2
1 0
0 1
0 1
0 1

出力例2

8

Solution in C# (judge verdict: Accepted)

using static System.Math;
using System.Linq;
using System;

public class hello
{
    public static void Main()
    {
        string[] line = Console.ReadLine().Trim().Split(' ');
        var m = int.Parse(line[0]);
        var n = int.Parse(line[1]);
        if (n == 1) { Console.WriteLine(getMax1(m)); goto exit; }
        if (n == 2) { Console.WriteLine(getMax2(m)); goto exit; }
        var map = new bool[n];
        line = Console.ReadLine().Trim().Split(' ');
        for (int i = 0; i < n; i++)
            if (line[i] == "0") map[i] = true;
        var ans = getMax3(map, n);
        for (int i = 1; i < m; i++)
        {
            line = Console.ReadLine().Trim().Split(' ');
            for (int j = 0; j < n; j++)
                if (line[j] == "1") map[j] = true;
                else map[j] = false;
            ans += getMax3(map, n);
        }
        Console.WriteLine(ans);
        exit:;
    }
    static int getMax2(int m)
    {
        var ans = 0;
        for (int i = 0; i < m; i++)
        {
            var s = Console.ReadLine().Trim();
            if (s == "0 0" | s == "1 1") ans++;
            else ans += 2;
        }
        return ans;
    }
    static int getMax1(int m)
    {
        var ans = int.Parse(Console.ReadLine().Trim());
        for (int i = 1; i < m; i++)
        {
            var t = int.Parse(Console.ReadLine().Trim());
            if (t == 0) ans++;
        }
        return ans;
    }
    static int getMax3(bool[] map, int n)
    {
        var c = map.Count(x => x == true);
        var c1 = c;
        if (map[0]) c1--;
        else c1++;
        var c2 = c;
        if (map[n - 1]) c2--;
        else c2++;
        var ans = Max(c1, c2);
        var b0 = c1;
        if (map[n - 1]) b0--;
        else b0++;
        for (int i = 1; i < n - 1; i++)
        {
            var t = b0;
            if (map[i]) t--;
            else
            {
                t++;
                ans = Max(ans, t);
                break;
            }
        }
        return ans;
    }
}