方格搜索

题目描述

设有N*N的方格图(N<=10,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0。如下图所示(见样例):

某人从图的左上角的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

看到一个很贵才的代码

来源
NOIP2000复赛 提高组 第四题

1. 设状态:f[i][j][h][k];//表示两条路同时走,第一条路径走到(i,j)时,第二条走到(h,k)时的最大数字和;
2. 初始状态:f[0][0][0][0]=0;
    最终状态:f[n][n][n][n];
3. 状态转移方程:当i==h&&j==k时,f[i][j][h][k]=max{f[i-1][j][h-1][k],f[i][j-1][h][k-1],f[i-1][j][h][k-1],f[i][j-1][h-1][k])+a[i][j];//取上上,左左,上左,左上四个方向的最大值加上当前的值;
当i!=h&&j!=k时,f[i][j][h][k]=max{f[i-1][j][h-1][k],f[i][j-1][h][k-1],f[i-1][j][h][k-1],f[i][j-1][h-1][k])+a[i][j]+a[h][k];//取上上,左左,上左,左上四个方向的最大值加上两条路径当前的值;

/*
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
*/
#include<iostream>
using namespace std;
int f[51][51][51][51]={0};//f[i][j][k][h],表示第一条路走都i,j的时候,第二条路走到k,h的时候 最大数字的和。
int a[100][100];//存储方格中的数字
int n,x,y,z;
int main()
{
    cin>>n;
    while(cin>>x>>y>>z&&x&&z&&y)
    {
        a[x][y]=z;
    }
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= n; j++)
        {
            for(int h = 1; h <= n; h++)
            {
                for(int k = 1; k <= n; k++)
                {
                    int temp1 = max(f[i-1][j][h-1][k],f[i][j-1][h][k-1]);//上上、左左
                    int temp2 = max(f[i][j-1][h-1][k],f[i-1][j][h][k-1]);//左上,上左
                    f[i][j][h][k] = max(temp1,temp2) + a[i][j]; //这一步是找到哪个方向最大并加上现在的数字
                    if(i!=h&&j!=k) f[i][j][h][k] += a[h][k]; //如果两条路不重复就更新和
                }
            }
        }
    }
    cout<<f[n][n][n][n]<<endl;
    return 0;
} 

作者:yanyanwenmeng
来源:CSDN
原文:https://blog.csdn.net/yanyanwenmeng/article/details/77073629

原文地址:https://www.cnblogs.com/sakuraXiYue/p/10741098.html

时间: 2024-08-30 10:50:26

方格搜索的相关文章

OpenJ_Bailian 4103 踩方格(搜索 动态规划 )

题目传送门OpenJ_Bailian 4103 描述 有一个方格矩阵,矩阵边界在无穷远处.我们做如下假设:a.    每走一步时,只能从当前方格移动一格,走到某个相邻的方格上:b.    走过的格子立即塌陷无法再走第二次:c.    只能向北.东.西三个方向走:请问:如果允许在方格矩阵上走n步,共有多少种不同的方案.2种走法只要有一步不一样,即被认为是不同的方案. 输入 允许在方格上行走的步数n(n <= 20) 输出 计算出的方案数量 样例输入 2 样例输出 7 解题思路: 1.递归:从 (i

搜索 素数方阵

一个比较麻烦的数独 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向Z博士请教,Z博士拿出了他最近发明的"靶形数独",作为这两个孩子比试的题目.靶形数独的方格同普通数独一样,在9格宽×9格高的大九宫格中有9个3格宽×3格高的小九宫格(用粗黑色线隔开的).在这个大九宫格中,有一些数字是已知的,根据这些数字,利用逻辑推理,在其他的空格上填入1到9的数字.每个数字在每个小九宫格内不能重复出现,每个

hdu 1045 要求全部逐一搜索完的深搜

#include<stdio.h> #include<string.h> int visit[10][10]; char map[10][10]; int n,ans,ss,t; int judge(int x,int y) { int k; if(x<0||x>=n||y<0||y>=n) return 0; if(visit[x][y]==1||map[x][y]=='X') return 0; for(k=x-1;k>=0;k--) { if(m

HDU 4499 Cannon (暴力搜索)

题意:在n*m的方格里有t个棋子,问最多能放多少个炮且每个炮不能互相攻击(炮吃炮) 炮吃炮:在同一行或同一列且中间有一颗棋子. #include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> #include <queue> #include <math.h> #define M 50 #define LL long long using

poj 1054 The Troublesome Frog (暴力搜索 + 剪枝优化)

题目链接 看到分类里是dp,结果想了半天,也没想出来,搜了一下题解,全是暴力! 不过剪枝很重要,下面我的代码 266ms. 题意: 在一个矩阵方格里面,青蛙在里面跳,但是青蛙每一步都是等长的跳, 从一个边界外,跳到了另一边的边界外,每跳一次对那个点进行标记. 现在给你很多青蛙跳过后的所标记的所有点,那请你从这些点里面找出 一条可能的路径里面出现过的标记点最多. 分析:先排序(目的是方便剪枝,break),然后枚举两个点,这两个 点代表这条路径的起始的两个点.然后是三个剪枝,下面有. 开始遍历时,

【58测试】【贪心】【离散】【搜索】【LIS】【dp】

第一题 大天使之剑 大意: 有n个怪,每个怪的ph 为 h[i],有三种攻击方式,普通攻击:一次打一个怪一滴血:重击(消耗1魔法值):一次打一个怪两滴血:群体攻击(消耗1魔法值):一次打所有怪一滴血.你有无数血,m个魔法值,每攻击一次怪后,还存活的所有怪会各攻击你一滴血.问你打完所有怪你最少被打了多少滴血. 解: 看到这道题,首先想到的是搜索,一种一种的搜,把所有情况都搜出来找最小.在草稿纸上再列一些数据就会发现,其实是个贪心.在有魔法值的时候,尽量全用于群体攻击更划算,然后没有了就普通攻击.那

[NOIP2009] 靶形数独(搜索+剪枝)

题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他 们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教, Z 博士拿出了他最近发明的"靶形数独",作为这两个孩子比试的题目. 靶形数独的方格同普通数独一样,在 9 格宽×9 格高的大九宫格中有 9 个 3 格宽×3 格 高的小九宫格(用粗黑色线隔开的).在这个大九宫格中,有一些数字是已知的,根据这些数字,利用逻辑推理,在其他的空格上填入 1 到 9 的数字.每个数字在每个

C - N皇后问题(搜索)

Description 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上. 你的任务是,对于给定的N,求出有多少种合法的放置方法. Input 共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量:如果N=0,表示结束. Output 共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量. Sample Input 1 8 5 0 Sample Output 1 92 10 题目位置 题目要求:输入

UVA-1604 Cubic Eight-Puzzle (双向BFS+状态压缩+限制搜索层数)

题目大意:立体的八数码问题,一次操作是滚动一次方块,问从初始状态到目标状态的最少滚动次数. 题目分析:这道题已知初始状态和目标状态,且又状态数目庞大,适宜用双向BFS.每个小方块有6种状态,整个大方格有9*6^8个状态.每个小方块用一位6进制数表示即可. 注意:状态转移时要谨慎,否则会出现意想不到的错误: 这道题的末状态有256(2^8)个,如果对搜索层数不加限制,即使双向BFS也会TLE的,当限制正向搜索15层逆向搜索15层至正向搜索27层反向搜索3层时都能AC(我下面贴出的程序是这样的),其