hdu2167 方格取数 状态压缩dp

题意:
     方格取数,八个方向的限制。
思路:
     八个方向的不能用最大流了,四个的可以,八个的不能抽象成二分图,所以目测只能
用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[n][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() == ' ') break;
       }
       n = nowid;
       for(i = 2 ;i <= n ;i ++)
       for(j = 1 ;j <= n ;j ++)
       scanf("%d" ,&map[i][j]);
       printf("%d " ,DP(n));
    }
    return 0;
}

原文地址:https://www.cnblogs.com/csnd/p/12062733.html