ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::
给定一个m行n列的矩阵,你可以从任意位置开始取数,到达任意位置都可以结束,每次可以走到的数是当前这个数上下左右的邻居之一,唯一的限制是每个位置只能经过一次,也就是说你的路径不自交。所经过的数的总作为你的得分,求最大的得分。
Input
第一行两个整数m, n (0 < m, n < 10),表示矩阵的行数和列数。
后面m行,每行n个整数表示矩阵里的数,整数范围[-10000000, +10000000]。
Output
一个整数表示最大得分。

插头dp,状态可以用滚动数组存

#include<cstdio>
#include<cstring>
int n,m;
int v[13][13];
int s0[1048576+7],s1[1048576+11];
bool po[1048576];
const int v0=-2147483647;
inline void maxs(int&a,int b){if(a<b)a=b;}
inline int _l(int x,int w){
    int t=1,a;
    do{
        w-=2;
        a=x>>w&3;
        t+=(a>>1)-(a&1);
    }while(t);
    return w;
}
inline int _r(int x,int w){
    int t=1,a;
    do{
        w+=2;
        a=x>>w&3;
        t-=(a>>1)-(a&1);
    }while(t);
    return w;
}
int main(){
    scanf("%d%d",&n,&m);
    int ans=v0;
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            scanf("%d",v[i]+j);
            if(v[i][j]>ans)ans=v[i][j];
        }
    }
    if(ans<=0)return printf("%d\n",ans),0;
    int mx=1<<2*(m+1);
    for(int i=0;i<mx;++i){
        int t=0;
        for(int j=0;j<=m;++j)t+=((i>>j*2&3)==3);
        po[i]=(t<=2);
    }
    for(int i=0;i<mx;++i)s1[i]=v0;
    s1[0]=0;
    for(int i=1;i<=n+1;++i){
        for(int j=1;j<=m;++j){
            for(int p=0;p<mx;++p){
                s0[p]=s1[p];
                s1[p]=v0;
            }
            for(int p=0;p<mx;++p)if(s0[p]!=v0&&po[p]){
                int tt=0;
                for(int t=0;t<=m;++t)tt+=(p>>t*2&1)+(p>>t*2+1&1);
                bool is=(tt==2);
                if(is)maxs(ans,s0[p]);
                int p1=j*2-2,p2=j*2;
                int a=p>>p1&3,b=p>>p2&3,c=s0[p]+v[i][j],d1=~(3<<j*2-2),d2=~(3<<j*2);
                switch(a){
                    case 0:{
                        switch(b){
                            case 0:{
                                maxs(s1[p],s0[p]);
                                maxs(s1[p|3<<p2],c);
                                maxs(s1[p|3<<p1],c);
                                maxs(s1[p|1<<p1|2<<p2],c);
                                break;
                            }
                            case 1:{
                                maxs(s1[p],c);
                                maxs(s1[p&d2|1<<p1],c);
                                maxs(s1[p&d1&d2|3<<_r(p,p2)],c);
                                break;
                            }
                            case 2:{
                                maxs(s1[p],c);
                                maxs(s1[p&d2|2<<p1],c);
                                maxs(s1[p&d1&d2|3<<_l(p,p1)],c);
                                break;
                            }
                            case 3:{
                                maxs(s1[p],c);
                                maxs(s1[p&d2|3<<p1],c);
                                break;
                            }
                        }
                        break;
                    }
                    case 1:{
                        switch(b){
                            case 0:{
                                maxs(s1[p&d1|1<<p2],c);
                                maxs(s1[p],c);
                                maxs(s1[p&d1|3<<_r(p,p2)],c);
                                break;
                            }
                            case 1:{
                                maxs(s1[p&d1&d2^3<<_r(p,p2)],c);
                                break;
                            }
                            case 3:{
                                maxs(s1[p&d1&d2|3<<_r(p,p2)],c);
                                break;
                            }
                        }
                        break;
                    }
                    case 2:{
                        switch(b){
                            case 0:{
                                maxs(s1[p&d1|2<<p2],c);
                                maxs(s1[p],c);
                                maxs(s1[p&d1|3<<_l(p,p1)],c);
                                break;
                            }
                            case 1:{
                                maxs(s1[p&d1&d2],c);
                                break;
                            }
                            case 2:{
                                maxs(s1[p&d1&d2^3<<_l(p,p1)],c);
                                break;
                            }
                            case 3:{
                                maxs(s1[p&d1&d2|3<<_l(p,p1)],c);
                                break;
                            }
                        }
                        break;
                    }
                    case 3:{
                        switch(b){
                            case 0:{
                                maxs(s1[p&d1|3<<p2],c);
                                maxs(s1[p],c);
                                break;
                            }
                            case 1:{
                                maxs(s1[p&d1&d2|3<<_r(p,p2)],c);
                                break;
                            }
                            case 2:{
                                maxs(s1[p&d1&d2|3<<_l(p,p1)],c);
                                break;
                            }
                            case 3:{
                                if(tt==4)maxs(ans,c);
                                break;
                            }
                        }
                        break;
                    }
                }
            }
            if(i==n+1)break;
        }
        for(int a=mx-4;a>=0;a-=4){
            s1[a+1]=s1[a+2]=s1[a+3]=v0;
            s1[a]=s1[a>>2];
        }
    }
    printf("%d",ans);
    return 0;
}

 

posted on 2016-09-20 20:00  nul  阅读(367)  评论(0编辑  收藏  举报