HDU1565 方格取数(1)(状态压缩dp)

时间:2021-09-15 19:32:25

题目链接

分析:

说这题是状态压缩dp,其实不是,怎么说呢,题目数据太水了,所以就过了。手动输入n=20的情况,超时。正解是网络流,不太会。

A这题时有个细节错了,是dp[i][j]还是dp[i][q[j]]? 答案是dp[i][j],因为q[j]必定会超(感谢CZ学长提示)。

AC代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
using namespace std; const int maxn = ; int q[maxn], dp[][maxn], G[][]; int main() {
int n; while(scanf("%d", &n) == ) {
int cn = ;
for(int i=; i<(<<n); i++) {
if((i & (i << )) == ) {
q[cn++] = i;
}
} for(int i=; i<=n; i++) {
for(int j=; j<=n; j++) {
scanf("%d", &G[i][j]);
}
} memset(dp, , sizeof(dp)); for(int i=; i<=n; i++) {
for(int j=; j<cn; j++) {
int ans = ;
for(int p=; p<n; p++) {
if((q[j]&(<<p)) != ) {
ans += G[i][p+];
}
} dp[i][j] = ans; for(int k=; k<cn; k++) {
if((q[j] & q[k]) == ) {
dp[i][j] = max(dp[i][j], dp[i-][k]+ans);
}
}
}
} int ans = -;
for(int i=; i<cn; i++) {
ans = max(ans, dp[n][i]);
} printf("%d\n", ans);
} return ;
}