zoukankan      html  css  js  c++  java
  • NOIP2000方格取数[DP]

    题目描述

    设有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条路径上取得的最大的和。

    输入输出样例

    输入样例#1:
    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
    
    输出样例#1:
    67

    说明

    NOIP 2000 提高组第四题

    --------------------------------

    同传纸条

    可以发现一定有一个最优解使得路径不重合

    注意最后一个格的价值只能贡献一次

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=55;
    int n,m,a[N][N],f[N<<1][N][N];
    void dp(){
        memset(f,0,sizeof(f));
        for(int i=2;i<=n+m;i++)
            for(int j=1;j<=i&&j<=m;j++)
                for(int k=1;k<=i&&k<=m;k++){
                    if(j==k&&i!=m+n) continue;
                    if(i-j>n||i-k>n) continue;
                    f[i][j][k]=max(f[i][j][k],f[i-1][j][k]);
                    f[i][j][k]=max(f[i][j][k],f[i-1][j-1][k-1]);
                    f[i][j][k]=max(f[i][j][k],f[i-1][j-1][k]);
                    f[i][j][k]=max(f[i][j][k],f[i-1][j][k-1]);
                    f[i][j][k]+=a[j][i-j]+a[k][i-k];
                    if(i==m+n&&j==k) f[i][j][k]-=a[j][i-j];
                    //printf("%d %d %d %d
    ",i,j,k,f[i][j][k]);
                }
    }
    int main(int argc, const char * argv[]) {
        cin>>n;m=n;
        for(int i=1;;i++){
                int x,y,w;
                scanf("%d%d%d",&x,&y,&w);
                if(w==0&&y==0&&x==0) break;
                a[x][y]=w;
            }
        dp();
        cout<<f[n+m][m][m];
        return 0;
    }
  • 相关阅读:
    jQuery 基本选择器
    JavaScriptif while for switch流程控制 JS函数 内置对象
    JavaScrip基本语法
    数据库 存储引擎 表的操作 数值类型 时间类型 字符串类型 枚举集合 约束
    数据库基础知识 管理员 用户登录授权的操作
    粘包的产生原理 以及如何解决粘包问题
    socket TCP DPT 网络编程
    2018年年终总结
    Android技术分享
    No accelerator found
  • 原文地址:https://www.cnblogs.com/candy99/p/5819961.html
Copyright © 2011-2022 走看看