using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("3 4");
WillReturn.Add("4 3 5");
WillReturn.Add("2 6 7 4");
WillReturn.Add("0100");
WillReturn.Add("1011");
WillReturn.Add("1010");
//9
}
else if (InputPattern == "Input2") {
WillReturn.Add("15 20");
WillReturn.Add("29 27 79 27 30 4 93 89 44 88 70 75 96 3 78");
WillReturn.Add("39 97 12 53 62 32 38 84 49 93 53 26 13 25 2 76 32 42 34 18");
WillReturn.Add("01011100110000001111");
WillReturn.Add("10101111100010011000");
WillReturn.Add("11011000011010001010");
WillReturn.Add("00010100011111010100");
WillReturn.Add("11111001101010001011");
WillReturn.Add("01111001100101011100");
WillReturn.Add("10010000001110101110");
WillReturn.Add("01001011100100101000");
WillReturn.Add("11001000100101011000");
WillReturn.Add("01110000111011100101");
WillReturn.Add("00111110111110011111");
WillReturn.Add("10101111111011101101");
WillReturn.Add("11000011000111111001");
WillReturn.Add("00011101011110001101");
WillReturn.Add("01010000000001000000");
//125
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static int[] mRArr;
static int[] mCArr;
static char[,] mBanArr;
static int UB_X;
static int UB_Y;
static void Main()
{
List<string> InputList = GetInputList();
mRArr = InputList[1].Split(' ').Select(pX => int.Parse(pX)).ToArray();
mCArr = InputList[2].Split(' ').Select(pX => int.Parse(pX)).ToArray();
mBanArr = CreateBanArr(InputList.Skip(3));
UB_X = mBanArr.GetUpperBound(0);
UB_Y = mBanArr.GetUpperBound(1);
long Result = ExecDP();
Console.WriteLine(Result);
}
static long ExecDP()
{
// 最小コスト[現在X , 現在Y , 現在列の反転有無 , 現在行の反転有無]
long[, , ,] DPArr = new long[UB_X + 1, UB_Y + 1, 2, 2];
for (int LoopX = 0; LoopX <= UB_X; LoopX++) {
for (int LoopY = 0; LoopY <= UB_Y; LoopY++) {
for (int I = 0; I <= 1; I++) {
for (int J = 0; J <= 1; J++) {
DPArr[LoopX, LoopY, I, J] = long.MaxValue;
}
}
}
}
// 開始状態01 (0列目も0行目も反転しない)
DPArr[0, 0, 0, 0] = 0;
// 開始状態02 (0列目のみ反転)
DPArr[0, 0, 1, 0] = mCArr[0];
// 開始状態03 (0行目のみ反転)
DPArr[0, 0, 0, 1] = mRArr[0];
// 開始状態04 (0列目も0行目も反転)
DPArr[0, 0, 1, 1] = mCArr[0] + mRArr[0];
// 配るDP
for (int LoopX = 0; LoopX <= UB_X; LoopX++) {
for (int LoopY = 0; LoopY <= UB_Y; LoopY++) {
for (int I = 0; I <= 1; I++) {
for (int J = 0; J <= 1; J++) {
if (DPArr[LoopX, LoopY, I, J] == long.MaxValue) continue;
long CurrVal = DPArr[LoopX, LoopY, I, J];
char CurrColor = mBanArr[LoopX, LoopY];
if (I == 1) CurrColor = GetHantnColor(CurrColor);
if (J == 1) CurrColor = GetHantnColor(CurrColor);
Action<int, int> SendAct = (pVectX, pVectY) =>
{
int TargetX = LoopX + pVectX;
int TargetY = LoopY + pVectY;
if (UB_X < TargetX) return;
if (UB_Y < TargetY) return;
char TargetColor = mBanArr[TargetX, TargetY];
// 横移動で現在行が反転している場合
if (pVectX == 1 && J == 1) {
TargetColor = GetHantnColor(TargetColor);
}
// 縦移動で現在列が反転している場合
if (pVectY == 1 && I == 1) {
TargetColor = GetHantnColor(TargetColor);
}
long NewVal = long.MaxValue;
long NewI = I;
long NewJ = J;
// 横移動の場合
if (pVectX == 1) NewI = 0;
// 縦移動の場合
if (pVectY == 1) NewJ = 0;
if (TargetColor != CurrColor) {
// 横移動の場合
if (pVectX == 1) {
NewVal = CurrVal + mCArr[TargetX];
NewI = 1;
}
// 縦移動の場合
if (pVectY == 1) {
NewVal = CurrVal + mRArr[TargetY];
NewJ = 1;
}
}
else {
NewVal = CurrVal;
}
if (DPArr[TargetX, TargetY, NewI, NewJ] <= NewVal) {
return;
}
DPArr[TargetX, TargetY, NewI, NewJ] = NewVal;
};
SendAct(0, 1);
SendAct(1, 0);
}
}
}
}
var AnswerKouho = new List<long>();
AnswerKouho.Add(DPArr[UB_X, UB_Y, 0, 0]);
AnswerKouho.Add(DPArr[UB_X, UB_Y, 0, 1]);
AnswerKouho.Add(DPArr[UB_X, UB_Y, 1, 0]);
AnswerKouho.Add(DPArr[UB_X, UB_Y, 1, 1]);
return AnswerKouho.Min();
}
// 色を引数として反転した色を返す
static char GetHantnColor(char pColor)
{
return pColor == '0' ? '1' : '0';
}
////////////////////////////////////////////////////////////////
// IEnumerable<string>をcharの2次元配列に設定する
////////////////////////////////////////////////////////////////
static char[,] CreateBanArr(IEnumerable<string> pStrEnum)
{
var StrList = pStrEnum.ToList();
if (StrList.Count == 0) {
return new char[0, 0];
}
int UB_X = StrList[0].Length - 1;
int UB_Y = StrList.Count - 1;
char[,] WillReturn = new char[UB_X + 1, UB_Y + 1];
for (int Y = 0; Y <= UB_Y; Y++) {
for (int X = 0; X <= UB_X; X++) {
WillReturn[X, Y] = StrList[Y][X];
}
}
return WillReturn;
}
}