UVAlive 6560 - The Urge to Merge(状压dp)

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;
}


posted @ 2017-05-31 09:20  wzjhoutai  阅读(148)  评论(0编辑  收藏  举报