• 三取方格数


    描述

    设有N*N的方格图,我们将其中的某些方格填入正整数,而其他的方格中放入0。

    某人从图得左上角出发,可以向下走,也可以向右走,直到到达右下角。在走过的路上,他取走了方格中的数。(取走后方格中数字变为0)此人从左上角到右下角共走3次,试找出3条路径,使得取得的数总和最大。

    格式

    输入格式

    第一行:N (4<=N<=20)
    接下来一个N*N的矩阵,矩阵中每个元素不超过80,不小于0

    输出格式

    一行,表示最大的总和。

    样例1

    样例输入1[复制]

     
    4
    1 2 3 4
    2 1 3 4
    1 2 3 4
    1 3 2 4

    样例输出1[复制]

     
    39

    限制

    各个测试点1s

    提示

    多进程DP

      f[step][x1][x2][x3]表示当走到第step步时,三个点分别取x1,x2,x3时的最优解。

      由于只能向下或向右移动,所以当移动步数一定时,所能移动到的格子是一个 / 的对角线,所以枚举三次移动到的横坐标,可以O(1)第算出纵坐标,注意每个方格只能取一次。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<algorithm>
     7 using namespace std;
     8 const int maxn=25;
     9 int f[maxn*2][maxn][maxn][maxn];
    10 int map[maxn][maxn];
    11 int N;
    12 int main(){
    13     
    14     scanf("%d",&N);
    15     for(int i=1;i<=N;i++){
    16         for(int j=1;j<=N;j++){
    17             scanf("%d",&map[i][j]);
    18         }
    19     }
    20     f[1][1][1][1]=map[1][1];
    21     for(int step=2;step<=2*N-1;step++){//枚举步数,假定走到 (1,1) 用了一步 
    22         for(int x1=max(1,step-N+1);x1<=min(N,step);x1++){//x1,x2,x3 是用 step步走到横坐标为 x1,x2,x3的方格,
    23             for(int x2=max(1,step-N+1);x2<=min(N,step);x2++){//用min(),max()都是保证方格不越界的方式 
    24                 for(int x3=max(1,step-N+1);x3<=min(N,step);x3++){
    25                     int delta=map[x1][step-x1+1]+map[x2][step-x2+1]+map[x3][step-x3+1];
    26                     if(x1==x2) delta-=map[x1][step-x1+1];
    27                     if(x1==x3) delta-=map[x1][step-x1+1];
    28                     if(x2==x3) delta-=map[x2][step-x2+1];
    29                     if(x1==x2&&x1==x3) delta+=map[x1][step-x1+1];//多减去了一次 
    30                     
    31                     f[step][x1][x2][x3]=max(f[step-1][x1][x2][x3],max(f[step-1][x1-1][x2][x3],
    32                                         max(f[step-1][x1][x2-1][x3],max(f[step-1][x1][x2][x3-1],
    33                                         max(f[step-1][x1-1][x2-1][x3],max(f[step-1][x1-1][x2][x3-1],
    34                                         max(f[step-1][x1][x2-1][x3-1],f[step-1][x1-1][x2-1][x3-1])))))))+delta;
    35                     
    36                     
    37                 }
    38             }
    39         }
    40     }
    41     cout<<f[2*N-1][N][N][N];
    42     return 0;
    43 }
  • 相关阅读:
    ExtJs自学教程(1):一切从API開始
    c++多态的案例分析
    pig中使用的一些实例语法
    6.跑步者--并行编程框架 ForkJoin
    移动加密那点事儿_值存储加密
    手工制作的年份Java老A发售量
    【C语言的日常实践(十六)】字符串输出功能puts、fputs和printf
    POJ 1852 Ants
    HDU 4793 2013 Changsha Regional Collision[简单的平面几何]
    BZOJ 1355 Baltic2009 Radio Transmission KMP算法
  • 原文地址:https://www.cnblogs.com/CXCXCXC/p/4786948.html
Copyright © 2020-2023  润新知