zoukankan      html  css  js  c++  java
  • 51nod 1411 矩阵取数问题 V3

    给定一个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
    ",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;
    }
  • 相关阅读:
    系统设计实现
    反编译
    android layout analyze
    2016.7.20-notes
    如何认识刘昊然?
    leetcode-中等-队列-二叉树的层次遍历
    leetcode-简单-栈-逆波兰表达式
    leetcode-简单-栈-有效的括号
    队列-链式队列
    队列-循环队列-顺序存储
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5890176.html
Copyright © 2011-2022 走看看