hdu 1565(状压dp入门题)

很明显,当前行的状态只与前一行有关
并且当前行的状态与前一行的状态(i&j)==0时才满足条件
预处理出每种可能的状态
从前往后枚举每一行的状态
再枚举前一行的状态
dp存储该状态下最优结果

#pragma warning (disable : 4996)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;

const int maxn = 1e6 + 10;
int dp[19][1 << 17];
int a[22][22];
int tot[maxn];//存所有可能状态

int get_sum(int row, int x) {
	int cnt = 1, res = 0;
	while (x) {
		if (x & 1)	res += a[row][cnt];
		x >>= 1, cnt++;
	}
	return res;
}

int main() {
	ios::sync_with_stdio(0);
	int n;
	while (cin >> n) {
		memset(dp, 0, sizeof dp);
		int cnt = 0, up = 1 << n;
		for (int i = 1; i <= n; ++i)	for (int j = 1; j <= n; ++j)	cin >> a[i][j];
		for (int i = 0; i < up; ++i) if ((i & (i >> 1)) == 0)	tot[cnt++] = i;
		for (int i = 1; i <= n; ++i) {
			for (int j = 0; j < cnt; ++j) {
				int val = get_sum(i, tot[j]);
				for (int k = 0; k < cnt; ++k) {
					if ((tot[j] & tot[k]) == 0)	dp[i][j] = max(dp[i][j], dp[i-1][k] + val);
				}
			}
		}
		int ans = 0;
		for (int i = 0; i < cnt; ++i)	ans = max(dp[n][i], ans);
		cout << ans << endl;
	}
	return 0;
}
posted @ 2020-09-29 22:49  wansheking  阅读(126)  评论(0)    收藏  举报