Problem:
Score : 300 points

Problem Statement

There are N stones arranged in a row. Every stone is painted white or black.
A string S represents the color of the stones. The i-th stone from the left is white if the i-th character of S is ., and the stone is black if the character is #.

Takahashi wants to change the colors of some stones to black or white so that there will be no white stone immediately to the right of a black stone.
Find the minimum number of stones that needs to be recolored.

Constraints

1 \leq N \leq 2\times 10^5

S is a string of length N consisting of . and #.

Input

Input is given from Standard Input in the following format:

N
S

Output

Print the minimum number of stones that needs to be recolored.

Sample Input 1

3
#.#

Sample Output 1

1

It is enough to change the color of the first stone to white.

Sample Input 2

5
#.##.

Sample Output 2

2

Sample Input 3

9
.........

Sample Output 3

0

Solution in C# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;

namespace Program
{
    interface Output
    {
        void Write(object str);
        void WriteLine(object str);
    }

    interface Input
    {
        int NextInt();
        string NextString();
    }

    class Console_ : Input, Output
    {
        Queue<string> param = new Queue<string>();
        int Input.NextInt()
        {
            if (param.Count == 0)
            {
                foreach (var item in Console.ReadLine().Split(' '))
                {
                    param.Enqueue(item);
                }
            }
            return int.Parse(param.Dequeue());
        }
        string Input.NextString()
        {
            if (param.Count == 0)
            {
                foreach (var item in Console.ReadLine().Split(' '))
                {
                    param.Enqueue(item);
                }
            }
            return param.Dequeue();
        }
        void Output.Write(object str)
        {
            System.Console.Write(str.ToString());
        }
        void Output.WriteLine(object str)
        {
            System.Console.WriteLine(str.ToString());
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            new Solver(new Console_(), new Console_()).Run();
        }
    }

    class Debug_ : Input
    {
        int i = 0;
        int Input.NextInt()
        {
            return (int)data[i++];
        }
        string Input.NextString()
        {
            return (string)data[i++];
        }
        object[] data =
        {
            15,
            "##.#...#.#.#"
        };
    }

    class Solver
    {
        Input input;
        Output output;
        public Solver(Input input, Output output)
        {
            this.input = input;
            this.output = output;
        }

        public void Run()
        {
            var N = input.NextInt();
            var S = input.NextString().Select(e => e == '.' ? false : true).ToArray();
            var list = new List<int>();
            int firstIdx = 0;
            for (int i = firstIdx; i < S.Length; ++i)
            {
                if (S[i])
                {
                    firstIdx = i;
                    break;
                }
            }
            bool before = true;
            int sumtmp = 0;
            for (int i = firstIdx; i < S.Length; ++i)
            {
                if (S[i] ^ before)
                {
                    list.Add(sumtmp);
                    sumtmp = 1;
                    before = !before;
                }
                else
                {
                    // same
                    ++sumtmp;
                }
            }
            list.Add(sumtmp);
            output.WriteLine(Count(list, 0));
        }

        static Dictionary<Tuple<int, int>, int> tmp = new Dictionary<Tuple<int, int>, int>();
        int Count(List<int> list, int idx)
        {
            if (list.Count <= idx + 1)
            {
                return 0;
            }
            var key = Tuple.Create(list[idx], idx);
            if (tmp.ContainsKey(key))
            {
                return tmp[key];
            }

            int res1 = list[idx];
            res1 += Count(list, idx + 2);
            int res2 = list[idx + 1];
            if (list[idx] < list[idx + 1]) return res1;
            if (idx + 2 < list.Count)
            {
                list[idx + 2] = list[idx] + list[idx + 1];
                res2 += Count(list, idx + 2);
            }
            tmp[key] = Math.Min(res1, res2);
            return tmp[key];
        }
    }
}