This question is a little simpler than the previous Little Kings. Without the limit on the number of steps, the DP equation is much simpler.
You only need to consider whether the current status conflicts with the previous status.
The Code is as follows:
# Include <cstdio>
# Include <cstring>
# Include <cstdlib>
# Include <iostream>
# Define maxn20000
Using namespace STD;
Long long f [25] [maxn];
Int n, m, map [25] [25], s [maxn];
Inline long max (long & X, long & Y)
{
Return x <Y? Y: X;
}
Void DFS (int l, int state)
{// List all statuses of each row
If (L = N)
{
S [++ m] = State;
Return;
}
DFS (L + 1, State <1 );
If (! (State & 1 ))
DFS (L + 1, State <1 | 1 );
}
Inline bool judge (INT S1, int S2)
{
If (s [S1] & S [s2])
Return false;
Else
Return true;
}
Inline int get (int x, int K)
{
Int ans = 0;
For (INT I = N, A = s [k]; A; -- I, A >>= 1)
{
If (A & 1)
Ans + = map [x] [I];
}
Return ans;
}
Void dp ()
{
For (INT I = 1; I <= m; ++ I)
F [1] [I] = get (1, I );
For (INT I = 2; I <= N; ++ I)
{
For (Int J = 1; j <= m; ++ J)
{
Int res = get (I, j );
For (int K = 1; k <= m; ++ K)
{
If (Judge (j, k ))
{
F [I] [J] = max (F [I] [J], F [I-1] [k] + Res );
}
}
}
}
}
Int main ()
{
Long long ans;
While (scanf ("% d", & n) = 1)
{
M = 0;
Ans = 0;
DFS (0, 0 );
For (INT I = 0; I <= N; ++ I)
{
For (Int J = 0; j <= m; ++ J)
F [I] [J] = 0;
}
For (INT I = 1; I <= N; ++ I)
{
For (Int J = 1; j <= N; ++ J)
{
Scanf ("% d", & map [I] [J]);
}
}
DP ();
For (INT I = 1; I <= m; ++ I)
{
Ans = max (ANS, F [N] [I]);
}
Cout <ans <Endl;
}
Return 0;
}