• 洛谷P1004方格取数


    链接:https://www.luogu.org/problem/show?pid=1004

    题目描述

    设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放

    人数字0。如下图所示(见样例):

    A
     0  0  0  0  0  0  0  0
     0  0 13  0  0  6  0  0
     0  0  0  0  7  0  0  0
     0  0  0 14  0  0  0  0
     0 21  0  0  0  4  0  0
     0  0 15  0  0  0  0  0
     0 14  0  0  0  0  0  0
     0  0  0  0  0  0  0  0
    .                       B

    某人从图的左上角的A点出发,可以向下行走,也可以向右走,直到到达右下角的B

    点。在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字0)。

    此人从A点到B点共走两次,试找出2条这样的路径,使得取得的数之和为最大。

    输入输出格式

    输入格式:

    输入的第一行为一个整数N(表示N*N的方格图),接下来的每行有三个整数,前两个

    表示位置,第三个数为该位置上所放的数。一行单独的0表示输入结束。

    输出格式:

    只需输出一个整数,表示2条路径上取得的最大的和。

    输入输出样例

    输入样例:
    8
    2 3 13
    2 6  6
    3 5  7
    4 4 14
    5 2 21
    5 6  4
    6 3 15
    7 2 14
    0 0  0
    输出样例:
    67
    solution:
    这题听说有人跑了个费用流……/斜眼笑
    反正我是用dp做的……

    记f[i][j][k][l]为第一遍取a[i][j],第二遍取a[k][l]的数时的最大值。
    很显然只能从它们来的地方转移。
    因此f[i][j][k][l]=max(f[i-1][j][k-1][l],f[i-1][j][k][l-1],f[i][j-1][k-1][l],f[i][j-1][k][l-1])+a[i][j]+a[k][l]-a[i][j]*(i==k && j==l);//仅当(i,j)和(k,l)为同一个坐标的时候需要去除重复加的a[i][j](因为a[i][j]只能被取用一次)
    然后我们就很愉快地得到了答案。即f[n][n][n][n]。
    代码:
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<cmath>
     7 using namespace std;
     8 int n;
     9 int a[20][20];
    10 int dp[20][20][20][20];
    11 int check(int a,int b,int c,int d){
    12     if(a==c && b==d)  return 1;
    13     else  return 0;
    14 }
    15 int main(){
    16     scanf("%d",&n);
    17     int i,j,k,l;
    18     int x,y,z;
    19     memset(a,0,sizeof(a));
    20     memset(dp,0,sizeof(dp));
    21     while(scanf("%d%d%d",&x,&y,&z)){
    22         if(x==0 && y==0 && z==0){
    23             break ;
    24         }
    25         a[x][y]=z;
    26     }
    27     for(i=1;i<=n;++i){
    28         for(j=1;j<=n;++j){
    29             for(k=1;k<=n;++k){
    30                 for(l=1;l<=n;++l){
    31                     dp[i][j][k][l]=max(max(dp[i-1][j][k][l-1],dp[i-1][j][k-1][l]),max(dp[i][j-1][k][l-1],dp[i][j-1][k-1][l]))+a[i][j]+a[k][l]-a[k][l]*check(i,j,k,l);
    32                 }
    33             }
    34         }
    35     }
    36     printf("%d\n",dp[n][n][n][n]);
    37     return 0;
    38 }
    View Code
    
    
  • 相关阅读:
    八十九:ECMAScript6扩展之字符串、for-of
    八十八:ECMAScript6之解构赋值
    八十七:ECMAScript6基础入门之let、const
    八十六:JavaScript之表单验证案例
    八十五:JavaScript之正则表达式之实现正则测试工具
    八十四:JavaScript之正则表达式之常用的正则表达式
    vim常用命令总结(转)
    Linux常用命令
    LinkedBlockingQueue的put,add跟offer的区别
    RabbitMQ消息确认(发送确认,接收确认)
  • 原文地址:https://www.cnblogs.com/lazytear/p/7755021.html
Copyright © 2020-2023  润新知