您的位置:首页 > 其它

hdu1565 方格取数(1)(状压dp)

2017-08-02 21:30 288 查看
可以状压搞,因为n很小,虽说复杂度到了4亿,但是数据确实水。

#include <bits/stdc++.h>

using namespace std;
const int MAXN = 20+5;
int n;
int tu[MAXN][MAXN];
int dp[2][1<<20];
void get_dp()
{
//记录两行的状态,每次枚举每一行的格点
for(int i = 0; i < n; ++i)
for(int j = 0; j < n; ++j)
{
//枚举第j个
int t = 1<<j;
//按照行的奇偶性,分开
int p = (i*n+j)%2;
//枚举上一行的状态
for(int state = 0; state < (1<<n); ++state)
{
//如果当前的位置j没有选,那么左右没有影响,上面可选 可 不选。
if((state & t) == 0)dp[!p][state] = max(dp[p][state+t],dp[p][state]);
//如果当前位置j选了,并且j-1也选了,那么不符合条件
else if(j && (state & (t>>1)))dp[!p][state] = 0;//这里踩坑(state & (t>>1))不是等于1而是要大于0
//当前j选了但是符合条件的情况,那么上面不能选
else dp[!p][state] = dp[p][state-t] + tu[i][j];
}
}
}

int main()
{
while(~scanf("%d",&n))
{
for(int i = 0; i < n; ++i)
for(int j = 0; j < n; ++j)scanf("%d",&tu[i][j]);
memset(dp,0,sizeof dp);
get_dp();
int MAX = 0;
int p = n*n%2;
for(int i = 0; i < (1<<n); ++i)MAX = max(MAX,dp[p][i]);
printf("%d\n",MAX);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  状压dp