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 ", ++cas, ans); } return 0; }