HDU 2167 状压DP

来源:互联网 发布:空中客车a380数据 编辑:程序博客网 时间:2024/05/22 08:11

方格取数问题,给出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[n]-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;}


0 0
原创粉丝点击