Problem:
Score : 800 points

Problem Statement

Mr. Takahashi has in his room an art object with H rows and W columns, made up of H \times W blocks.
Each block has a color represented by a lowercase English letter (a-z).
The color of the block at the i-th row and j-th column is c_{i,j}.

Mr. Takahashi would like to dismantle the object, finding it a bit kitschy for his tastes.
The dismantling is processed by repeating the following operation:

Choose one of the W columns and push down that column one row.
The block at the bottom of that column disappears.

Each time the operation is performed, a cost is incurred.
Since blocks of the same color have a property to draw each other together, the cost of the operation is the number of the pairs of blocks (p, q) such that:

The block p is in the selected column.

The two blocks p and q are horizontally adjacent (before pushing down the column).

The two blocks p and q have the same color.

Mr. Takahashi dismantles the object by repeating the operation H \times W times to get rid of all the blocks.
Compute the minimum total cost to dismantle the object.

Constraints

1 ≤ H ≤ 300

2 ≤ W ≤ 300

All characters c_{i,j} are lowercase English letters (a-z).

Partial Score

In test cases worth 300 points, W = 3.

Input

The input is given from Standard Input in the following format:

H W
c_{1,1}c_{1,2}..c_{1,W}
c_{2,1}c_{2,2}..c_{2,W}
:
c_{H,1}c_{H,2}..c_{H,W}

Output

Print the minimum total cost to dismantle the object.

Sample Input 1

2 3
rrr
brg

Sample Output 1

2

For example, the total cost of 2 can be achieved by performing the operation as follows and this is the minimum value.

Sample Input 2

6 3
xya
xya
ayz
ayz
xaz
xaz

Sample Output 2

0

The total cost of 0 can be achieved by first pushing down all blocks of the middle column, then all of the left column, and all of the right column.

Sample Input 3

4 2
ay
xa
xy
ay

Sample Output 3

0

The total cost of 0 can be achieved by the following operations:

pushing down the right column one row;

pushing down the left column one row;

pushing down all of the right column;

and pushing down all of the left column.

Sample Input 4

5 5
aaaaa
abbba
ababa
abbba
aaaaa

Sample Output 4

24

Sample Input 5

7 10
xxxxxxxxxx
ccccxxffff
cxxcxxfxxx
cxxxxxffff
cxxcxxfxxx
ccccxxfxxx
xxxxxxxxxx

Sample Output 5

130

Solution in Ruby (2.3.3) (judge verdict: Wrong Answer)


hw = gets.chomp.split(" ").map(&:to_i)
if hw[1] == 3
ret = []
hw[0].times do
 b = gets.chomp.split("").map{|t| t.ord}
 ret << b
end

bk= []

hw[1].times do |i|
  bk << ret.map{|t| t[i]}.reverse
end
#p bk

hsh = {}

def cost(a, b)
  return 100000 if a.nil? || b.nil?
  sml = (a.size - b.size) > 0 ? b.size : a.size
  cst = 0
  for i in 0..sml-1 do
    cst += 1 if a[i] == b[i]
  end
return cst
end

RCOST=Array.new(hw[0]).map{Array.new(hw[0], -1)}
LCOST=Array.new(hw[0]).map{Array.new(hw[0], -1)}

def rcost(bk, a,b)
  return 0 if a>=bk[0].size || b>=bk[0].size
  return RCOST[a][b] if RCOST[a][b] != -1
  sml = a > b ? a : b
  cst = 0
  for i in 0..(bk[0].size - sml-1) do
    cst += 1 if bk[0][a+i] == bk[1][b+i]
  end
  RCOST[a][b] = cst
  return cst
end


def lcost(bk, a,b)
  return 0 if a>=bk[0].size || b>=bk[0].size
  return LCOST[a][b] if LCOST[a][b] != -1
  sml = a > b ? a : b
  cst = 0
  for i in 0..(bk[0].size - sml-1) do
    cst += 1 if bk[1][a+i] == bk[2][b+i]
  end
  LCOST[a][b] = cst
  return cst
end

dp2 = Array.new(hw[0]+2).map{Array.new(hw[0]+2).map{Array.new(hw[0]+2, -1)}}
p dp2[0][2]
dp = {}
#for i in 0..hw[0]*hw[1] do
#  lc = cost(bk[0], bk[1])
#  cr = cost(bk[1], bk[2])
#  if lc < cr
#  else
#  end
#end

#queue = []
vsted={}
queue = [[0,0,0]]
dp[[0,0,0]]=0
dp2[0][0][0]=0

while queue != []#for i in 1..g
  subset = queue.shift
  next if vsted[subset]
  vsted[subset]=true
  #crt = dp[subset]
  a = subset[0]
  b = subset[1]
  c = subset[2]
  crt = dp2[a][b][c]
  #next if a > hw[0] || b>hw[0] || c>hw[0]
    #lc = cost(bk[0][a..-1], bk[1][b..-1]) + cost(bk[1][b..-1], bk[2][c..-1])+crt
    lc = rcost(bk,a,b)+lcost(bk,b,c)+crt
    #dp[[a,b+1,c]] = lc if !dp[[a,b+1,c]] || dp[[a,b+1,c]] > lc
    dp2[a][b+1][c] = lc if dp2[a][b+1][c]==-1 || dp2[a][b+1][c] > lc
    #lc2 = cost(bk[0][a..-1], bk[1][b..-1]) +crt
    lc2 = rcost(bk,a,b)+crt#bk[0][a..-1], bk[1][b..-1]) +crt
    #dp[[a+1,b,c]] = lc if !dp[[a+1,b,c]] || dp[[a+1,b,c]] > lc
    dp2[a+1][b][c] = lc if dp2[a+1][b][c]==-1 || dp2[a+1][b][c] > lc
    #lc3 = cost(bk[1][b..-1], bk[2][c..-1])+crt
    lc3 = lcost(bk,b,c)+crt
    #dp[[a,b,c+1]] = lc if !dp[[a,b,c+1]] || dp[[a,b,c+1]] > lc
    dp2[a][b][c+1] = lc if dp2[a][b][c+1]==-1 || dp2[a][b][c+1] > lc
    queue << [a,b+1,c] if b < hw[0]
    queue << [a,b,c+1] if c < hw[0]
    queue << [a+1,b,c] if a < hw[0]
end
=begin
  #ans = 0
  for i in 0..((hw[0]-1)*hw[1]+1) do
    lc = cost(bk[0], bk[1][1..-1]) + cost(bk[1][1..-1], bk[2])
    lc2 = cost(bk[0][1..-1], bk[1]) + cost(bk[1], bk[2])
    lc3 = cost(bk[0], bk[1]) + cost(bk[1], bk[2][1..-1])
    if lc < lc2 && lc < lc3
    lc = cost(bk[0], bk[1]) + cost(bk[1], bk[2])
    ans += lc# + cr
    bk[1].shift
    elsif lc2 < lc3
    lc = cost(bk[0], bk[1]) #+ cost(bk[1], bk[2])
    ans += lc# + cr
    bk[0].shift
    else
    lc = cost(bk[2], bk[1]) #+ cost(bk[1], bk[2])
    ans += lc# + cr
    bk[2].shift
    end
    p [bk, ans]
    #ans += lc# + cr
    #nxtcst(bk)
  end
=end
  p dp2[hw[0]][hw[0]][hw[0]]
else

end