【HDU 2167】 Pebbles

【题目链接】

           点击打开链接

【算法】

          状压DP

          先搜出一行符合的情况,然后,f[i][j]表示第i行,状态为j,能够取得的最大值,DP即可

【代码】

         

#include<bits/stdc++.h>
using namespace std;
#define MAXN 16
const int MAXS = 65536;

int i,j,k,n,tot,ans,val,MASK;
int a[MAXN][MAXN],f[MAXN][MAXS],ST[MAXS];
char c;

int main()
{
    
    while (scanf("%d",&a[1][1]) != EOF)
    {
        n = 1;
        tot = ans = 0;
        memset(f,0,sizeof(f));
        scanf("%c",&c);
        while (c != '
')
        {
            scanf("%d",&a[1][++n]);
            scanf("%c",&c);    
        }    
        for (i = 2; i <= n; i++)
        {
            for (j = 1; j <= n; j++)
            {
                scanf("%d",&a[i][j]);
            }
        }
        MASK = (1 << n) - 1;
        for (i = 0; i <= MASK; i++)
        {
            if (i & (i << 1)) continue;
            ST[++tot] = i;
            for (j = 0; j < n; j++)
            {    
                if (i & (1 << j)) 
                    f[1][tot] += a[1][j+1];    
            } 
        }
        for (i = 2; i <= n; i++)
        {
            for (j = 1; j <= tot; j++) 
            {
                val = 0;
                for (k = 0; k < n; k++)
                {
                    if (ST[j] & (1 << k))
                        val += a[i][k+1];
                }
                for (k = 1; k <= tot; k++)
                {
                    if (ST[j] & ST[k]) continue;
                    if (ST[j] & (ST[k] >> 1)) continue;
                    if (ST[j] & (ST[k] << 1)) continue;
                    f[i][j] = max(f[i][j],f[i-1][k] + val);
                }
            }
        }
        for (i = 1; i <= n; i++)
        {
            for (j = 1; j <= tot; j++)
            {
                ans = max(ans,f[i][j]);
            }
        }
        printf("%d
",ans);
        scanf("%c",&c);
    }
    
    return 0;
}


          
原文地址:https://www.cnblogs.com/evenbao/p/9196347.html