zoukankan      html  css  js  c++  java
  • HDU 3377 Plan (插头DP)

    Plan

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 449    Accepted Submission(s): 151


    Problem Description
    One day, Resty comes to an incredible world to seek Eve -- The origin of life. Lilith, the sister of Eve, comes with him. Although Resty wants to find Eve as soon as possible, Lilith likes to play games so much that you can't make her make any move if you don't play with her.

    Now they comes to the magical world and Lilish ask Resty to play with her.

    The game is following :
    Now the world is divided into a m * n grids by Lilith, and Lilith gives each grid a score.
    So we can use a matrix to describe it.
    You should come from cell(0, 0) to cell(m-1, n-1) (Up-Left to Down-Right) and try to colloct as more score as possible.
    According to Lilish's rule, you can't arrive at each cell more than once.

    Resty knows that Lilish will be easy to find the max score, and he doesn't want to lose the game.
    So he want to find the game plan to reach the max score.

    Your task is to calculate the max score that Lilish will find, the map is so small so it shouldn't be difficult for you, right?
     
    Input
    The input consists of more than one testdata.
    Process to the END OF DATA.
    For each test data :
    the first live give m and n. (1<=m<=8, 1<=n<=9)
    following m lines, each contain n number to give you the m*n matrix.
    each number in the matrix is between -2000 and 2000
     
    Output
    Output Format is "Case ID: ANS" one line for each data
    Don't print any empty line to the output
     
    Sample Input
    2 2 1 2 3 1 3 3 0 -20 100 1 -20 -20 1 1 1
     
    Sample Output
    Case 1: 5 Case 2: 61
     
    Author
    Resty
     
    Source
     
    Recommend
    lcy
     
     
    插头DP
    /*
    HDU 3377
    从左上角走到右下角。每个格子有个分数。
    每个格子只能经过一次,可以不经过
    求最大分数
    G++ 140ms
    */
    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    
    const int MAXD=15;
    const int HASH=10007;
    const int STATE=1000010;
    
    int N,M;
    int maze[MAXD][MAXD];
    int score[MAXD][MAXD];
    int code[MAXD];
    int ch[MAXD];
    
    struct HASHMAP
    {
        int head[HASH],state[STATE],next[STATE],size;
        int dp[STATE];
        void init()
        {
            size=0;
            memset(head,-1,sizeof(head));
        }
        void push(int st,int ans)
        {
            int i,h=st%HASH;
            for(i=head[h];i!=-1;i=next[i])
               if(state[i]==st)
               {
                   if(dp[i]<ans)dp[i]=ans;
                   return;
               }
            state[size]=st;
            dp[size]=ans;
            next[size]=head[h];
            head[h]=size++;
        }
    }hm[2];
    void decode(int *code,int m,int st)
    {
        for(int i=m;i>=0;i--)
        {
            code[i]=st&7;
            st>>=3;
        }
    }
    int encode(int *code,int m)
    {
        int cnt=1;
        memset(ch,-1,sizeof(ch));
        ch[0]=0;
        int st=0;
        for(int i=0;i<=m;i++)
        {
            if(ch[code[i]]==-1)ch[code[i]]=cnt++;
            code[i]=ch[code[i]];
            st<<=3;
            st|=code[i];
        }
        return st;
    }
    void shift(int *code,int m)
    {
        for(int i=m;i>0;i--)code[i]=code[i-1];
        code[0]=0;
    }
    
    void dpblank(int i,int j,int cur)
    {
        int k,left,up;
        for(k=0;k<hm[cur].size;k++)
        {
            decode(code,M,hm[cur].state[k]);
            left=code[j-1];
            up=code[j];
            if((i==1&&j==1)||(i==N&&j==M))
            {
                if((left&&(!up))||((!left)&&up))
                {
                    code[j-1]=code[j]=0;
                    if(j==M)shift(code,M);
                    hm[cur^1].push(encode(code,M),hm[cur].dp[k]+score[i][j]);
                }
                else if(left==0&&up==0)
                {
                    if(maze[i][j+1])
                    {
                        code[j-1]=0;
                        code[j]=13;
                        hm[cur^1].push(encode(code,M),hm[cur].dp[k]+score[i][j]);
                    }
                    if(maze[i][j+1])
                    {
                        code[j-1]=13;
                        code[j]=0;
                        if(j==M)shift(code,M);
                        hm[cur^1].push(encode(code,M),hm[cur].dp[k]+score[i][j]);
                    }
                }
                continue;
            }
            if(left&&up)
            {
                if(left==up)//没有这种情况,因为不形成环
                {
    
                }
                else
                {
                    code[j-1]=code[j]=0;
                    for(int t=0;t<=M;t++)//这里少了个等号,查了好久的错
                      if(code[t]==up)
                        code[t]=left;
                    if(j==M)shift(code,M);
                    hm[cur^1].push(encode(code,M),hm[cur].dp[k]+score[i][j]);
                }
            }
            else if((left&&(!up))||((!left)&&up))
            {
                int t;
                if(left)t=left;
                else t=up;
                if(maze[i][j+1])
                {
                    code[j-1]=0;
                    code[j]=t;
                    hm[cur^1].push(encode(code,M),hm[cur].dp[k]+score[i][j]);
                }
                if(maze[i+1][j])
                {
                    code[j]=0;
                    code[j-1]=t;
                    if(j==M)shift(code,M);
                    hm[cur^1].push(encode(code,M),hm[cur].dp[k]+score[i][j]);
                }
            }
            else
            {
                if(maze[i][j+1]&&maze[i+1][j])
                {
                    code[j]=code[j-1]=13;
                    hm[cur^1].push(encode(code,M),hm[cur].dp[k]+score[i][j]);
                }
                code[j-1]=code[j]=0;
                if(j==M)shift(code,M);
                hm[cur^1].push(encode(code,M),hm[cur].dp[k]);
            }
        }
    }
    
    void init()
    {
        memset(maze,0,sizeof(maze));
        for(int i=1;i<=N;i++)
          for(int j=1;j<=M;j++)
          {
              maze[i][j]=1;
              scanf("%d",&score[i][j]);
          }
    }
    void solve()
    {
        int i,j,cur=0;
        hm[cur].init();
        hm[cur].push(0,0);
        for(int i=1;i<=N;i++)
          for(int j=1;j<=M;j++)
          {
              hm[cur^1].init();
              dpblank(i,j,cur);
              cur^=1;
          }
        int ans=0;
        for(int i=0;i<hm[cur].size;i++)
           ans+=hm[cur].dp[i];
        printf("%d\n",ans);
    }
    int main()
    {
       // freopen("in.txt","r",stdin);
       // freopen("out.txt","w",stdout);
        int iCase=0;
        while(scanf("%d%d",&N,&M)!=EOF)
        {
            iCase++;
            printf("Case %d: ",iCase);
            init();
            if(N==1&&M==1)
            {
                printf("%d\n",score[1][1]);
                continue;
            }
            solve();
        }
        return 0;
    }
    
    /*
    Sample Input
    2 2
    1 2
    3 1
    3 3
    0 -20 100
    1 -20 -20
    1   1   1
    
    
    Sample Output
    Case 1: 5
    Case 2: 61
    
    */
    人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想
  • 相关阅读:
    HTML(六)——表单验证、正则表达式、事件
    ADO。Net(二)——防止SQL注入攻击
    ADO.Net(一)——增、删、改、查
    【转】高性能服务器架构(High-Performance Server Architecture)
    【Python】使用Python将Shellcode转换成汇编
    【技术知识】恶意PDF文件分析-PDFdump的问题
    【逆向工具】IDA Python安装与使用
    【windows核心编程】HideProcess
    Virut.ce-感染型病毒分析报告
    【黑客免杀攻防】读书笔记11
  • 原文地址:https://www.cnblogs.com/kuangbin/p/2709773.html
Copyright © 2011-2022 走看看