您的位置:首页 > 其它

hdu2167 方格取数 状态压缩dp

2014-10-03 14:11 323 查看
题意:

方格取数,八个方向的限制。

思路:

八个方向的不能用最大流了,四个的可以,八个的不能抽象成二分图,所以目测只能
用dp来跑,dp[i][j]表示的是第i行j状态的最优,具体看代码。












#include<stdio.h>

#include<string.h>

int dp[16][1<<15];

int map[16][16];

int zt[1<<15];

int maxx(int x ,int y)

{

return x > y ? x : y;

}

int DP(int n)

{

int mk = 0;

for(int i = 0 ;i < (1<<n) ;i ++)

if((i & (i << 1)) == 0 ) zt[++mk] = i;



memset(dp ,0 ,sizeof(dp));

for(int i = 1 ;i <= n ;i ++)

for(int j = 1 ;j <= mk ;j ++)

{

int sum = 0;

for(int k = 1 ;k <= n ;k ++)

if(zt[j] & (1 << (k - 1))) sum += map[i][k];

dp[i][j] = sum;

for(int k = 1 ;k <= mk ;k ++)

{

if(zt[j] & zt[k]) continue;

if(zt[j] & zt[k]<<1) continue;

if(zt[j] & zt[k]>>1) continue;

dp[i][j] = maxx(dp[i][j] ,dp[i-1][k] + sum);

}

}

int Ans = 0;

for(int i = 1 ;i <= mk ;i ++)

Ans = maxx(Ans ,dp
[i]);

return Ans;

}

int main ()

{

int n ,i ,j ,nowid;

while(~scanf("%d" ,&map[1][1]))

{

nowid = 1;

while(1)

{

scanf("%d" ,&map[1][++nowid]);

if(getchar() == '\n') break;

}

n = nowid;

for(i = 2 ;i <= n ;i ++)

for(j = 1 ;j <= n ;j ++)

scanf("%d" ,&map[i][j]);

printf("%d\n" ,DP(n));

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: