洛谷千题详解 | P1004 [NOIP2000 提高组] 方格取数【C++、Java、Pascal语言】

news2025/2/24 7:19:53

博主主页:Yu·仙笙

专栏地址:洛谷千题详解

目录

题目描述

输入格式

输出格式

输入输出样例

解析: 

C++源码: 

Java源码: 

Pascal源码:


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

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

题目描述

设有 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

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

解析: 

这道题深搜的最优方法就是两种方案同时从起点出发。因为如果记录完第一种方案,再计算第二种方案,不可控的因素太多了,大多都不是最优解→_→,但两种方案同时执行就行,因为这可以根据当前的情况来判断最优。

总的来说,每走一步都会有四个分支(你理解成选择或者情况也可以):

1、两种都向下走

2、第一种向下走,第二种向右走

3、第一种向右走,第二种向下走

4、两种都向右走

每走一步走枚举一下这四种情况,因为在每个点的方案具有唯一性(也就是在某个点走到终点的取数方案只有一个最优解,自己理解一下),所以我们可以开一个数组来记录每一种情况,当重复枚举到一种情况时就直接返回(对,就是剪枝),大大节省了时间(不然会超时哦~)。深搜和动归的时间复杂度时一样的!

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

C++源码: 

#include<cstdio>
#include<algorithm>
using namespace std;
struct point
{
    int x,y,data;//记录每个点的位置和数值
}p[100];
int n,m,map[11][11],f[11][11];
int main()
{
    int i,ii,j,jj,l;
    scanf("%d",&n);
    while(1)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        if(!a&&!b&&!c)
            break;
        p[++m].x=a;
        p[m].y=b;
        p[m].data=c;
    }
    for(i=1;i<=m;i++)
        map[p[i].x][p[i].y]=p[i].data;
    for(l=2;l<=n*2;l++)//每个点最少横着竖着都走一格,最多都走n格就到终点
        for(i=l-1;i>=1;i--)//和前面说的一样,倒着做
            for(ii=l-1;ii>=1;ii--)
            {
                j=l-i;jj=l-ii;//i+j=ii+jj=l
                f[i][ii]=max(max(f[i][ii],f[i-1][ii-1]),max(f[i-1][ii],f[i][ii-1]))+map[i][j];
//重点说明一下吧,这里省略了很多。如果i不减1,意思就是j-1,因为上一个阶段就是l-1嘛。如果ii-1,意思就是说jj不减1。
                f[i][ii]+=map[ii][jj]*(i!=ii);
//如果i==ii,其实就是(i==ii&&j==jj),因为和都是l嘛。如果走过一遍,第二遍走得到的值就是0(题目上说的)。
            }
    printf("%d\n",f[n][n]);
//输出意思是在路径长度为2*n的阶段,两遍都走到(n,n)的最优值。因为在这里(j=2*n-i=n,jj=2*n-ii=n),所以走到的就是(n,n)的位置
    return 0;

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

Java源码: 

import java.util.Scanner;
 
public class Main{
     public static void main(String[] args) {
         Scanner reade=new Scanner(System.in);
         int n=reade.nextInt();
         int [][]num=new int[n+1][n+1];
         while (true) {
             int x = reade.nextInt();
             int y = reade.nextInt();
             int total = reade.nextInt();
             if (x == 0 && y == 0 && total == 0)
                 break;
             num[x][y] = total;
         }
         int [][][][]f=new int[10][10][10][10];
         for (int x1 = 1; x1 <= n; x1++) {
             for (int y1 = 1; y1 <= n; y1++) {
                 for (int x2 = 1; x2 <= n; x2++) {
                     for (int y2 = 1; y2 <= n; y2++) {
 
                         f[x1][y1][x2][y2] = Math.max(
                                 Math.max(f[x1 - 1][y1][x2 - 1][y2], f[x1 - 1][y1][x2][y2 - 1]),
                                 Math.max(f[x1][y1 - 1][x2 - 1][y2], f[x1][y1 - 1][x2][y2 - 1]));
                         f[x1][y1][x2][y2] += num[x1][y1];
                         if ( x1 !=x2 && y1 != y2) {
                             f[x1][y1][x2][y2] += num[x2][y2];
                         }
                     }
                 }
             }
         }
         System.out.println(f[n][n][n][n]);
 
 
     }
 
 
 }

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

Pascal源码:

var n,m,i,j,l,p,x,y,o:longint;
     fl:array[0..100] of array[0..100] of longint;  //棋盘
     board:array[-2..51] of array[-2..51] of array[-2..51] of array[-2..51] of longint;   
   function canread:boolean;
     begin
     canread:=false;
     if (x<>0)and(y<>0)and(o<>0) then canread:=true;
     exit; 
     end;
     begin
     readln(n);
     m:=n;
     readln(x,y,o);
     while canread do
     begin
     fl[x,y]:=o; readln(x,y,o);
     end;
     for i:=1 to m do  
     for j:=1 to n do
     for l:=1 to m do
     for p:=1 to n do {**枚举**两条路分别走到的位置}
     begin
     if board[i-1,j,l-1,p]>board[i,j,l,p] then board[i,j,l,p]:=board[i-1,j,l-1,p];         //上上
     if board[i-1,j,l,p-1]>board[i,j,l,p] then board[i,j,l,p]:=board[i-1,j,l,p-1];         //左上
 if board[i,j-1,l-1,p]>board[i,j,l,p] then board[i,j,l,p]:=board[i,j-1,l-1,p];        //左左
 if board[i,j-1,l,p-1]>board[i,j,l,p] then board[i,j,l,p]:=board[i,j-1,l,p-1];        //上左
 



     inc(board[i,j,l,p],fl[i,j]);    //加上该点的值
     if (i<>l)and(j<>p) then inc(board[i,j,l,p],fl[l,p]);       //second
     end;
     writeln(board[m,n,m,n]);
     end.


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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2734.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

KMP算法模式匹配——手工求解next和nextval数组值

本文需要了解KMP算法基本流程和相关概念&#xff0c;如有问题&#xff0c;请先进行基础学习&#xff1a;链接: 天勤-KMP算法易懂版 求解next数组值 给定模式串&#xff1a;“ababaaab”&#xff0c;求解其next数组值。 例子里面的ababaaab&#xff0c;我们定义一个 i 为模式串的…

【微服务】Nacos Discovery--服务治理

Nacos Discovery--服务治理前言服务治理常见的注册中心ZookeeperEurekaConsulNacosNacos 入门搭建nacos环境将商品微服务注册到nacos将订单微服务注册到nacos总结前言 上一章中&#xff0c;我们利用用户–订单–商品&#xff0c;实现了三个简单的微服务&#xff0c;实现了微服…

如何寻找计算机领域的英文文献?

大家一定或多或少都有文献检索的经验吧&#xff0c;中文文献还好&#xff0c;我们总归是对自己的的母语比较熟悉&#xff0c;通过关键词或其他检索条件&#xff0c;总能得心应手地找到自己需要的文献。相较于中文文献&#xff0c;对外文文献的检索就显得难度增加了不少&#xf…

pthread_create创建线程失败问题排查

一些基础概念的了解 Android中线程&#xff08;Thread&#xff09;的创建及内存分配过程分析 pthread_create创建线程失败的OOM详解 不可思议的OOM 通过上面的文章&#xff0c;我们知道为什么会报pthread_create错误 在创建线程的时候&#xff0c;报的下面这些错误&#xff0…

SAP采购订单中的净价是单价还是总价?

在采购订单中习惯上我们把订单项目的的净价理解为什么&#xff1f;单价还是总价&#xff1f; 先不着急回答。看看以下两个采购订单的对比截图就能了解&#xff0c; 在4050004000这笔采购订单中&#xff0c;采购10件黄色箱子&#xff0c;每10件500元。所以&#xff0c;净价500…

《JavaSE-第十七章》之LinkedList

前言 在你立足处深挖下去,就会有泉水涌出!别管蒙昧者们叫嚷:“下边永远是地狱!” 博客主页&#xff1a;KC老衲爱尼姑的博客主页 博主的github&#xff0c;平常所写代码皆在于此 刷题求职神器 共勉&#xff1a;talk is cheap, show me the code 作者是爪哇岛的新手&#xff0c;水…

Python Excel导入Mysql的通用方法

文章目录一、前言二、实现一、前言 此代码将导入部分尽量通用&#xff0c;仅配置下面两项就可以进行导入了&#xff1a; 从哪个excel导入到哪个mysql表 在程序中配置 他们之间的字段如何对应 写在mysql表中 ps&#xff1a;id&#xff0c;create_time&#xff0c;update_tim…

基于IDEA创建SpringBoot项目并进行入门分析

基于IDEA创建SpringBoot项目并进行入门分析 文章目录基于IDEA创建SpringBoot项目并进行入门分析SpringBoot 项目创建创建Module项目结构分析SpringBoot 项目启动分析启动入口启动过程概要分析SpringBoot 快速入门分析业务描述API设计分析代码编写及运行运行过程中的BUG分析Spri…

单商户商城系统功能拆解26—营销中心—限时秒杀

单商户商城系统&#xff0c;也称为B2C自营电商模式单店商城系统。可以快速帮助个人、机构和企业搭建自己的私域交易线上商城。 单商户商城系统完美契合私域流量变现闭环交易使用。通常拥有丰富的营销玩法&#xff0c;例如拼团&#xff0c;秒杀&#xff0c;砍价&#xff0c;包邮…

数电学习(六、时序逻辑电路)(三)

文章目录时序逻辑电路的设计方法同步时序逻辑电路的设计方法一般步骤改进步骤例&#xff1a;蚂蚁走迷宫背景分析继续编码状态&#xff0c;然后写出状态图&#xff0c;然后卡诺图化简&#xff0c;得到方程设计总结时序逻辑电路的设计方法 同步时序逻辑电路的设计方法 一般步骤…

2022最新SpringCloud面试题附完整答案

一、选择题 1.启动Ribbon的类注解是: ( ) A RibbonClient B EnableClient C EnableDisscoveryClient D Ribbon 2.下面哪个注解不是SpringbootApplication包含的默认属性值&#xff1a;&#xff08; &#xff09; A: Configuration B: EnableAutoConfiguration C: ComponentSc…

【LINUX】Linux最常用的20个基本指令 介绍~分析

什么是 Linux ​ Linux 是一款基于 GNU 通用公共许可协议 的 自由和开放源代码 的类UNIX操作系统&#xff0c;该操作系统的内核由 Linus Torvalds 在1991年首次发布。之后&#xff0c;在加上用户空间的应用程序之后&#xff0c;就成为了Linux操作系统。 但是&#xff0c;严格来…

springboot充电桩综合管理系统

目录 1 绪论 1 1.1 课题背景 1 1.2 课题研究现状 1 1.3 初步设计方法与实施方案 2 1.4 本文研究内容 2 2 系统开发环境 4 2.1 Java技术 4 2.2 JSP技术 4 2.3 B/S模式 4 2.4 MyEclipse环境配置 5 2.5 MySQL环境配置 5 2.6 SSM框架 6 3 系统分析 7 3.1 系统可行性分析 7 3.1.1 经…

基于 BP 神经网络特征提取的指纹识别应用(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑…

【每日训练】排序子序列

目录 题目链接&#xff1a; 输入输出描述&&测试用例&#xff1a; 解析&#xff1a; 程序&#xff1a; 题目链接&#xff1a; 排序子序列_牛客笔试题_牛客网 (nowcoder.com) 输入输出描述&&测试用例&#xff1a; 测试用例&#xff1a; 输入&#xff1a; 6 1…

设计模式之美总结(重构篇)

title: 设计模式之美总结&#xff08;重构篇&#xff09; date: 2022-10-27 17:31:42 tags: 设计模式 categories:技术书籍及课程 cover: https://cover.png feature: false 文章目录1. 概述1.1 重构的目的&#xff1a;为什么要重构&#xff08;why&#xff09;&#xff1f;1.…

10月业务安全月报 | 美国将奇虎360和知道创宇列入黑名单;丰田泄露30万用户信息;苹果曝严重漏洞

导语&#xff1a;随着数字化的深入普及&#xff0c;业务愈加开放互联。企业的关键数据、用户信息、基础设施、运营过程等均处于边界模糊且日益开放的环境中&#xff0c;涉及利益流和高附加值的业务面临多样的安全隐患&#xff0c;随时可能遭遇损失&#xff0c;进而影响企业运营…

HashMap底层源码分析

文章目录HashMap底层源码分析1.观察HashMap成员变量1.1 HashMap的主要成员变量1.2 HashMap的构造方法1.3 put方法HashMap底层源码分析 前言 &#xff1a; 上文我们已经将哈希表学完了&#xff0c;下面就来简单的看一下源码&#xff0c;就结束我们的Map和Set 的学习   1.观察H…

灰度级形态学 - 顶帽变换和底帽变换

目录 1. 介绍 2. 代码实现 1. 介绍 顶帽变换和底帽变换就是图像的加减和开闭运算的结合 顶帽变换的公式为&#xff1a;原图 - 原图的开运算 这里结合开运算的几何图形解释来介绍顶帽变换。 因为开运算是结构元从下往上推动的过程&#xff0c;所以会删除图像灰度值相对周围高…

Dom对象总结案例实操(第二十课)

Dom对象总结案例实操(第二十课) 今天文章有点长 第一部分:回顾之前Dom对象我用了四篇文章对他进行了分开讲述Dom对象的用途,今天用几个案例实操一下. 之前我们Dom对象中了解过下面的内容 Dom对象的定义?Dom对象的节点操作&#xff0c;了解到了父节点 子节点 第一个 子节点 最…