[HDU 2167]Pebbles:状压DP

来源:互联网 发布:python计算器源代码 编辑:程序博客网 时间:2024/06/05 14:14

点击这里查看原题

比HDU1565更复杂的一道状压DP,需要多记录一位左上角的情况。每次换行的时候不需要考虑左上角,但是需要将每一位左移一位

图转自http://blog.csdn.net/sf____/article/details/15026397
这里写图片描述

/*User:SmallLanguage:C++Problem No.:2167*/#include<bits/stdc++.h>#define ll long long#define inf 999999999using namespace std;int n,p,q,tot,t,a[20][20];ll f[2][1<<16],ans;int main(){    freopen("data.in","r",stdin);//    ios::sync_with_stdio(false);    while(1){        memset(f,-1,sizeof(f));        p=0,q=1;        n=16;        t=0;        f[q][0]=0;        //读入        for(int i=0;i<n;i++){            for(int j=0;j<n;j++){                char ch;                if(scanf("%d%c",&a[i][j],&ch)==-1) return 0;                t++;                if(ch=='\n'&&n==16) n=t;            }        }        tot=1<<n+1;        for(int i=0;i<n;i++){            for(int j=0;j<n;j++){                swap(p,q);                memset(f[q],-1,sizeof(f[q]));                for(int s=0;s<tot;s++){                    if(~f[p][s]==0) continue;                    if(j==0){//如果换行,此时无需考虑左上角,直接抛弃最高位                        int ss=(s<<1)&(~(1<<(n+1)));                        f[q][ss&(~1)]=max(f[q][ss&(~1)],f[p][s]);                        if(!(s&(1<<j))&&!(s&(1<<j+1)))                            f[q][ss^(1<<j)]=max(f[q][ss^(1<<j)],f[p][s]+a[i][j]);                        continue;                    }                    //不取                    f[q][s&(~(1<<j))]=max(f[q][s&(~(1<<j))],f[p][s]);                    if(!(s&(1<<j))&&!(s&(1<<(j+1)))&&!(s&(1<<(j-1)))&&!(s&(1<<(j+2))))//j-1为上一位,j为左上角,j+1为本位,j+2为下一位                        f[q][s^(1<<j)]=max(f[q][s^(1<<j)],f[p][s]+a[i][j]);                }            }        }        ans=0;        for(int s=0;s<tot;s++) ans=max(ans,f[q][s]);        printf("%lld\n",ans);    }    return 0;}
0 0