hdu2167Pebbles dp+状态压缩水题

来源:互联网 发布:d2d网络 编辑:程序博客网 时间:2024/06/06 00:26
/*
  比较简单的状态压缩
  状态转移方程dp[i][j]=max(dp[i-1][s]+count(i,useful[j]))
  dp[i][j]表示第i行的状态是第j个有效状态时的最大值
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 20
#define maxs 1<<15
int dp[maxn][maxs];//dp[i][j]第i的状态为j时取得的最大值
int board[maxn][maxn];
int useful[maxs];//满足条件的状态
int n;
int count(int i,int t)//dii行状态为t时的取值
{
    int pos=0;
    int ans=0;
    while(t)
    {
        if(t%2)
        ans+=board[i][pos];
        t/=2;pos++;
    }
    return ans;
}
int init()
{
    int upper=1<<n;
    int k=0;int i;
    for(i=0;i<upper;i++)
    {
        if((i&(i<<1))||(i&(i>>1)))
        continue;
        useful[k++]=i;
    }
    for(i=0;i<k;i++)
    dp[0][i]=count(0,useful[i]);
    return k;
}
int DP()
{
    memset(dp,-1,sizeof(dp));
    int topper=init();
    int i,j,k;
    for(i=1;i<n;i++)
    {
        for(j=0;j<topper;j++)
        {
            if(dp[i-1][j]==-1)
            continue;
            for(k=0;k<topper;k++)
            {
                if((useful[j]&useful[k])||(useful[j]&(useful[k]<<1))||(useful[j]&(useful[k]>>1)))
                continue;
                dp[i][k]=max(dp[i][k],dp[i-1][j]+count(i,useful[k]));
            }
        }
    }
    int ans=0;
    for(int j=0;j<topper;j++)
    ans=max(ans,dp[n-1][j]);
    printf("%d\n",ans);
}
int main()
{
    int t;int i;
    int j;char c;
    while(scanf("%d%c",&board[0][0],&c)!=EOF)
    {
        if(c=='\n')
        n=1;
        for(j=1;;j++)
        {
            scanf("%d%c",&board[0][j],&c);
            if(c=='\n')
            {
                n=j+1;
                break;
            }
        }
        for(i=1;i<n;i++)
        for(j=0;j<n;j++)
        scanf("%d",&board[i][j]);
        DP();
    }
    return 0;
}









0 0
原创粉丝点击