照猫画虎写了道入门题。。讲道理这东西我不应该现在才来学TAT
//状态压缩DP入门题
//九宫格的相邻限制条件
//N*N 3<=N<=15
/*
dp[i][j]表示前i行,最后一行状态为j时得到的最大分数和
对于一行j的所有可能可以用DFS弄出来,在同行搜索的时候只要保证行不相邻。
在判断合法状态转移的时候,判断本身、左移和右移即可。
dp[i][j] = max{dp[i-1][k] + sum[i][j]},其中k为和j不冲突的状态。
s[0]表示状态总数,s[i]表示第i个状态。
sum[i][j]表示第i行第j个状态的和
*/
#include <bits/stdc++.h>
using namespace std;
char str[100];
int n,len,ans;
int a[20][20], sum[20][40000];
int dp[20][40000];
int s[40000];
void dfs(int x, int last, int now)//last表示上一个格子有没有放,now表示当前状态
{
if (x > n)
{
s[++s[0]] = now;
return ;
}
dfs(x+1, 0, now << 1);
if (!last)
dfs(x+1, 1, now << 1 | 1);
}
int main()
{
int i1 = 0;
while (gets(str))
{
i1++;
len = strlen(str);
if (len)
{
n = (len + 1) / 3;
for (int j=0;j<n;j++)
a[i1][j+1] = (str[3*j] - 48) * 10 + (str[3*j+1] - 48);
}
else
{
i1 = 0;
s[0] = 0;
dfs(1,0,0);
for (int i=1;i<=n;i++)
for (int j=1;j<=s[0];j++)
{
sum[i][j] = dp[i][j] = 0;
for (int k = 1;k<=n;k++)
if ((s[j] & (1<<(n-k))) != 0)
{
sum[i][j] += a[i][k];
}
for (int k = 1;k<=s[0];k++)
{
if ((s[j] & s[k]) == 0 && (s[j] & (s[k] << 1)) == 0 && (s[j] & (s[k] >> 1)) == 0)
{
dp[i][j] = max(dp[i][j], dp[i-1][k] + sum[i][j]);
}
}
}
ans = 0;
for (int i=1;i<=s[0];i++)
ans = max(ans, dp[n][i]);
printf("%d\n", ans);
}
}
}