hdu 3377 Plan

来源:互联网 发布:剑三成女捏脸数据图片 编辑:程序博客网 时间:2024/06/06 04:46

昨晚熬夜把它给切了,1y,这题可以相当于poj 1739+hdu 1964的加强版,我的做法是在最左边和最下边加上一层外围,权值全为0,然后就是插头dp了,不过要注意的是,题目不要求全部格子都经过,所以有一边插头的格子一定要有另一边,而没有插头的格子可以选择放两个插头,或者不放,另外要再注意下加的那两层的插头状态是确定的。

Run IDSubmit TimeJudge StatusPro.IDExe.TimeExe.MemoryCode Len.LanguageAuthor68601462012-10-04 01:56:38Accepted337762MS548K3256BC++xym2010

#include<cstdio>#include<cstring>#include<string>#include<cmath>#include<iostream>#include<algorithm>#define LL intusing namespace std;const int maxn=30001,INF=1<<30;int mov[12]={0,2,4,6,8,10,12,14,16,18,20,22};struct node{    int size,head[maxn],next[maxn];    LL sta[maxn],sum[maxn];    void clear()    {        memset(head,-1,sizeof(head));        size=0;    }    void push(int st,int v)    {        int hash=st%maxn;        for(int i=head[hash];i>=0;i=next[i])        {            if(sta[i]==st)            {                sum[i]=max(sum[i],v);                return;            }        }        sta[size]=st,sum[size]=v;        next[size]=head[hash],head[hash]=size++;    }}dp[2];inline int getbit(int st,int k){return 3&(st>>mov[k]);}inline int pybit(int st,int k){return st<<mov[k];}inline int clrbit(int st,int a,int b){return st&(~(3<<mov[a]))&(~(3<<mov[b]));}int fl(int st,int k,int r){    int cnt=1;    for(int i=k+1;i<=r;i++)    {        int e=getbit(st,i);        if(e==2) cnt--;        else if(e==1) cnt++;        if(cnt==0) return i;    }}int fr(int st,int k){    int cnt=1;    for(int i=k-1;i>=0;i--)    {        int e=getbit(st,i);        if(e==2) cnt++;        else if(e==1) cnt--;        if(cnt==0) return i;    }}int n,m,gp[20][20];LL DP(){    int ans=-INF;    dp[0].clear();    dp[0].push(0,0);    int now=0,pre=1;    for(int i=1;i<=n;i++)    {        pre=now,now^=1,dp[now].clear();        for(int j=0;j<dp[pre].size;j++)            dp[now].push(dp[pre].sta[j]<<2,dp[pre].sum[j]);        for(int j=1;j<=m;j++)        {            pre=now,now^=1,dp[now].clear();            for(int k=0;k<dp[pre].size;k++)            {                int l=getbit(dp[pre].sta[k],j-1);                int up=getbit(dp[pre].sta[k],j);                int st=clrbit(dp[pre].sta[k],j-1,j);//                printf("%d %d %d %d %d %d %d\n",i,j,l,up,st,dp[pre].sta[k],dp[pre].sum[k]);                if(!l&&!up)                {                    if(i==1&&j==1)                        dp[now].push(st|pybit(1,j-1)|pybit(2,j),dp[pre].sum[k]+gp[i][j]);                    else                    {                        if(i<n&&j<m)                        dp[now].push(st|pybit(1,j-1)|pybit(2,j),dp[pre].sum[k]+gp[i][j]);                        dp[now].push(st,dp[pre].sum[k]);                    }                }                else if(!l||!up)                {                    int e=l==0?up:l;                    if(j==1&&i!=n&&l==0)                        dp[now].push(st|pybit(e,j-1),dp[pre].sum[k]+gp[i][j]);                    else if(i==n&&j!=m&&up==0)                        dp[now].push(st|pybit(e,j),dp[pre].sum[k]+gp[i][j]);                    else                    {                        if(i<n)                            dp[now].push(st|pybit(e,j-1),dp[pre].sum[k]+gp[i][j]);                        if(j<m)                            dp[now].push(st|pybit(e,j),dp[pre].sum[k]+gp[i][j]);                    }                }                else if(l==1&&up==1&&j!=1&&i!=n)                    dp[now].push(st^pybit(3,fl(st,j,n)),dp[pre].sum[k]+gp[i][j]);                else if(l==2&&up==2&&j!=1&&i!=n)                    dp[now].push(st^pybit(3,fr(st,j-1)),dp[pre].sum[k]+gp[i][j]);                else if(l==2&&up==1&&j!=1&&i!=n)                    dp[now].push(st,dp[pre].sum[k]+gp[i][j]);                else if(i==n&&j==m)                    dp[now].push(st,dp[pre].sum[k]+gp[i][j]);            }        }    }    for(int i=0;i<dp[now].size;i++)        if(dp[now].sta[i]==0)            return dp[now].sum[i];        return 0;}int main(){    int t=1;    while(~scanf("%d%d",&n,&m))    {            memset(gp,0,sizeof(gp));        for(int i=1;i<1+n;i++)            for(int j=2;j<m+2;j++)                scanf("%d",&gp[i][j]);        n++,m++;    /*    for(int i=1;i<=n;i++)        {            for(int j=1;j<=m;j++)                printf("%d ",gp[i][j]);            puts("");        }*/        printf("Case %d: %d\n",t++,DP());    }    return 0;}