LA 6560 - The Urge to Merge
思路:状压dp,1表示要和下一个位置竖直乘,0表示不,这样递推下去即可
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1005;
const int INF = 0x3f3f3f3f;
int g[N][3], dp[2][8], n;
bool judge(int u, int f) {
for (int i = 0; i < 3; i++)
if (u&(1<<i) && f&(1<<i)) return false;
return true;
}
int cal(int x, int u, int f) {
int ans = 0;
for (int i = 0; i < 3; i++) {
if (f&(1<<i))
ans += g[x][i] * g[x - 1][i];
}
int s = u|f;
int tmp1 = 0, tmp2 = 0;
if (!(s&1) && !(s&2)) tmp1 = g[x][0] * g[x][1];
if (!(s&2) && !(s&4)) tmp2 = g[x][1] * g[x][2];
ans += max(tmp1, tmp2);
return ans;
}
int main() {
int cas = 0;
while (~scanf("%d", &n) && n) {
for (int i = 0; i < 3; i++)
for (int j = 1; j <= n; j++)
scanf("%d", &g[j][i]);
memset(dp[0], 0, sizeof(dp[0]));
int now = 0, pre = 1;
int ans = 0;
for (int i = 1; i <= n; i++) {
swap(now, pre);
memset(dp[now], 0, sizeof(dp[now]));
for (int j = 0; j < 8; j++) {
for (int k = 0; k < 8; k++) {
if (judge(j, k)) {
dp[now][j] = max(dp[now][j], dp[pre][k] + cal(i, j, k));
}
}
if (i == n) ans = max(ans, dp[now][j]);
}
}
printf("Case %d: %d\n", ++cas, ans);
}
return 0;
}