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