您的位置:首页 > 其它

hdu 2167 状态压缩dp

2014-09-19 16:58 183 查看
/*
状态转移方程:dp[i][j]=Max(dp[i][j],dp[i-1][k]+sum[i][j]);
*/
#include<stdio.h>
#include<string.h>
#define N   16
int ma

;
int num
;
char s[150];
int lower[15];//储存二级制
int dp
[1<<N];//储存最优状态
int now[1<<N],cu;//储存合法的状态
int sum
[1<<N];//储存第i行第j个状态的总的权值和
int Max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int n,i,j,k,maxx;
lower[0]=1;
for(i=1; i<=15; i++)
lower[i]=lower[i-1]*2;
while(gets(s))
{
k=0;
j=0;
n=0;
for(i=0; s[i]; i++)
{
if(j&&s[i]==' ')
{
ma[1][++n]=k;
j=0;
k=0;
}
if(s[i]>='0'&&s[i]<='9')
{
k=k*10+s[i]-'0';
j=1;
}
}
if(j)
ma[1][++n]=k;
for(i=2; i<=n; i++)
for(j=1; j<=n; j++)
scanf("%d",&ma[i][j]);
cu=0;
for(i=0; i<(1<<n); i++)//储存合法的状态
{
if(i<<1&i)continue;
now[++cu]=i;
}
memset(sum,0,sizeof(sum));
memset(dp,0,sizeof(dp));
for(i=1; i<=n; i++)
for(j=1; j<=cu; j++)
for(k=0; k<n; k++)//因为在二进制中1代表的就是lower[0],如果k从1开始的话,lower[1]=2,就缺少了1的情况
if(lower[k]&now[j])sum[i][j]+=ma[i][k+1];//lower[k]才是有效地
for(i=1; i<=cu; i++)//初始化第一行
dp[1][i]=sum[1][i];
for(i=2; i<=n; i++)
for(j=1; j<=cu; j++)
for(k=1; k<=cu; k++)
{
if(now[j]&now[k])continue;
if(now[j]&(now[k]<<1))continue;//如果和对角线和上面都没有相邻就符合
if(now[j]&(now[k]>>1))continue;
dp[i][j]=Max(dp[i][j],dp[i-1][k]+sum[i][j]);
}
maxx=-1;
for(i=1; i<=cu; i++)//求出所有状态的最大值
if(maxx<dp
[i])
maxx=dp
[i];
printf("%d\n",maxx);
gets(s);
gets(s);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: