# 逃离地牢

int val( type x )
{
int ret = 0;
while(x % 12 == 0) {
x /= 12;
ret++;
}
return ret;
}

3
12 1 24
6 3 4
4 4 16
0


Case #1: 3


12 可以质因数分解为2 ^ 2 , 3所以就是找2和 3的数量最小值的最大，状态转移方程就是当前因子数= max(上一步,现在)；


# include <iostream>
# include <cstdio>
# include <algorithm>
# include <cstring>

using namespace std;

const int maxn = 1e2 + 10;
int dp[maxn][maxn][2010];
int f[maxn][maxn][2];
int main(int argc, char *argv[])
{
int n;
int ca = 1;
while(cin >> n, n)
{

int ans = 0;
memset(f, false, sizeof(f));
memset(dp,-1, sizeof(dp));
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
int x;
cin >> x;
int k1 = 0, k2 = 0;
while(x % 2 == 0)
{
x /= 2;
k1++;
}
while(x % 3 == 0)
{
x /= 3;
k2++;
}
f[i][j][0] = k1;//2的个数
f[i][j][1] = k2;//3的个数
}

for(int i = 0; i <= n; i++)
for(int j = 0; j <= n; j++)
dp[i][j][0] = 0;
for(int i = 0; i <= n; i++)
{
for(int j = 0; j <= n; j++)
{
for(int p = f[i][j][0]; p <= 2000; p++)
{
if(i == 0 || j == 0)
{
continue;
}
if(dp[i - 1][j][p - f[i][j][0]] != -1)//当前我这一步的2因子数是由上一步的2的因子数结合而来的,3的因子数也是
{
dp[i][j][p] = max(dp[i][j][p], dp[i - 1 ][j][p - f[i][j][0]] + f[i][j][1]);
}
if(dp[i][j - 1][p - f[i][j][0]] != -1)//当前我这一步的2因子数是由上一步的2的因子数结合而来的,3的因子数也是
{
dp[i][j][p] = max(dp[i][j][p], dp[i][j - 1][p - f[i][j][0]] + f[i][j][1]);
}
}
}
}
for(int i = 0; i <= 2000; i++)
ans = max(min(dp[n][n][i],i / 2), ans);
cout<<"Case #"<<ca++<<": "<<ans<<endl;

}
return 0;
}