• [wikioi]传纸条


    http://wikioi.com/problem/1169/

    棋盘型的动态规划,这道题可以看成是从左上角向右下角走两条不重合的路(除了开始和结尾)。动态规划要想的是状态和阶段,状态是(x1,y1,x2,y2),两个分别一步一步走,所以阶段就是L=x+y。这样状态也能简化成三维(L, x1, x2)。约束是其中每一部两个棋子不能重合(如果重合就设为0)。状态转移是每一步都可以从之前的四个状态走过来,比较取最大值就行。

    如果用循环的方式写,则L从小到大,x1,x2也从小到大循环。这里用了备忘录方式写,就比较方便。

    #include <cstdio>
    #include <iostream>
    #include <memory.h>
    using namespace std;
    const int MAX_N = 51;
    int M,N;
    int G[MAX_N][MAX_N];
    int f[MAX_N*2][MAX_N][MAX_N]; // L, X1, X2
    void init()
    {
        int i,j;
        scanf("%d %d",&M,&N);
        for (i=1;i<=M;i++)
        for (j=1;j<=N;j++)
        scanf("%d",&G[i][j]);
        memset(f,-1,sizeof(f));
    }
    bool isValid(int a,int b,int c,int d)
    {
        if (a>M||c>M) return false;
        if (b>N||d>N) return false;
        if (a<1||c<1) return false;
        if (b<1||d<1) return false;
        return true;
    }
    int process(int L,int x1,int x2)
    {
        if (L==2) return 0;
        int y1 = L-x1;
        int y2 = L-x2;
        if (!isValid(x1,y1,x2,y2)) return 0;
        if (x1==x2&&y1>=y2&&!(x1==M&&y1==N)) return 0;
        if (f[L][x1][x2]!=-1) return f[L][x1][x2]; 
        int tmp=0;
        tmp=max(tmp,process(L-1,x1,x2));
        tmp=max(tmp,process(L-1,x1,x2-1));
        tmp=max(tmp,process(L-1,x1-1,x2));
        tmp=max(tmp,process(L-1,x1-1,x2-1));
        return f[L][x1][x2]=tmp+G[x1][y1]+G[x2][y2];
    }
    int main()
    {
        init();
        printf("%d",process(M+N,M,M));
        return 0; 
    }
    

      

  • 相关阅读:
    gitlab 安装升级
    fping 命令
    sed 命令
    rm 命令
    sort 命令
    第十六单元
    第十五单元
    第十三单元
    第十二单元
    第十一单元
  • 原文地址:https://www.cnblogs.com/lautsie/p/3347804.html
Copyright © 2020-2023  润新知