您的位置:首页 > 其它

HDU 2167 状压DP

2015-07-25 16:46 323 查看
方格取数问题,给出n*n矩阵,3<n<15

求能取得的最大和,要求取某个位置的数以后,其周围的8个数字均不能再取

先预处理出来所有的可取状态,n=15时只有1597个状态,然后地推求解即可

#include "stdio.h"
#include "string.h"
int n,ans;
int b[21],a[21][21],s[1700];
int dp[21][70001],sum[21][70001];

int Max(int a,int b)
{
if (a<b) return b;
else return a;
}
void DP()
{
int tot,cnt,i,j,k;
tot=b
-1;
cnt=0;
memset(dp,0,sizeof(dp));
memset(sum,0,sizeof(sum));

for (i=0;i<=tot;i++)
{
if ((i<<1)&i) continue;
s[cnt++]=i;
}
for (i=0;i<n;i++)
for (j=0;j<cnt;j++)
for (k=0;k<n;k++)
if (b[k]&s[j])
sum[i][j]+=a[i][k];

for (i=0;i<cnt;i++)
dp[0][i]=sum[0][i];

for (i=1;i<n;i++)
for (j=0;j<cnt;j++)
for (k=0;k<cnt;k++)
{
if (s[j]&s[k]) continue;
if ((s[j]<<1)&s[k]) continue;
if ((s[j]>>1)&s[k]) continue;
dp[i][j]=Max(dp[i][j],dp[i-1][k]+sum[i][j]);
}

ans=0;
for (i=0;i<cnt;i++)
ans=Max(ans,dp[n-1][i]);

}

int main()
{
int i,k,j;
char str[101];
b[0]=1;
for (i=1;i<=20;i++)
b[i]=b[i-1]*2;

while (gets(str))
{
n=(strlen(str)+2)/3;
k=0;
for (i=0;i<str[i];i+=3)
a[0][k++]=(str[i]-'0')*10+str[i+1]-'0';

for (i=1;i<n;i++)
for (j=0;j<n;j++)
scanf("%d",&a[i][j]);

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

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