/*
有个穷困的艺术家。他画了一幅超现实主义的作品《方块手拉手》。现在他已经把图画中手拉手的一排大小不一的方块都画出来了。现在要考虑上颜色了。可惜他手中的钱并不多了。但是他是个有追求的人,他希望这幅画中每两个相邻的方块的颜色是不一样的。你能帮他计算一下把这幅画上色后,最少需要花多少钱么。
输入 N个方块,K个颜色
接下来每列是各个方块染成不同颜色的价钱
输出 最少花的钱
例:
4 3
2 3 2
9 1 4
7 8 1
2 8 3
6
*/
#include <vector>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <limits.h>
using namespace std;
/*暴力法:
int minCost(vector<vector<int>>& costs)
{
int min_1=1000000;
for (int i1=0; i1<3; i1++) {
int min_2=0,min_3,min_4,min_5;
min_2+=costs[0][i1];
for (int i2=0; i2<3; i2++) {
if (i2==i1)
continue;
else{
min_3=min_2;
min_3+=costs[1][i2];
}
for (int i3=0; i3<3; i3++) {
if (i3==i2)
continue;
else{
min_4=min_3;
min_4+=costs[2][i3];
}
for (int i4=0; i4<3&&i4!=i3; i4++) {
if (i4==i3)
continue;
else{
min_5=min_4;
min_5+=costs[3][i4];
if (min_5<min_1)
min_1=min_5;
}
}
}
}
}
return min_1;
}
*/
//动态规划法
int N,K;
int minCost(vector<vector<int>> costs){
for (int i=N-2; i>=0; i--) {//从倒数第二行开始,每一项加上下面一项里最小的数值
for (int j=0;j<K ; j++) {
int MIN=1000000;
for (int r=0; r<K; r++) {
if (r==j)
continue;
if (costs[i][j]+costs[i+1][r]<MIN)
MIN=costs[i][j]+costs[i+1][r];
}
costs[i][j]=MIN;
}
}
int min=1000000;
for (int i=0; i<K; i++)
if (costs[0][i]<min)//最后得出最顶一项中的最小值
min=costs[0][i];
return min;
}
int main()
{
int cost;
vector<vector<int> > costs;
string s;
istringstream is;
getline(cin, s);
is.str(s);
is>>N>>K;
for(int i =0 ; i < N; i++)
{
vector<int> t;
getline(cin, s);
is.clear();
is.str(s);
for(int j = 0; j < K; j++) {
is >> cost;
t.push_back(cost);
}
costs.push_back(t);
}
cout<<minCost(costs)<<endl;
return 0;
}