洛谷p1732 活蹦乱跳的香穗子 二维DP

今天不BB了,直接帖原题吧  地址>>https://www.luogu.org/problem/show?pid=1732<<

题目描述

香穗子在田野上调蘑菇!她跳啊跳,发现自己很无聊,于是她想了一个有趣的事情,每个格子最多只能经过1次,且每个格子都有其价值

跳的规则是这样的,香穗子可以向上下左右四个方向跳到相邻的格子,并且她只能往价值更高(这里是严格的大于)的格子跳.

香穗子可以从任意的格子出发,在任意的格子结束,

那么她最多能跳几次?

输入输出格式

输入格式:

第一行n,m,表示田野的长和宽

接下来n行,每行m个数,表示该格的价值


输出格式:

一个数,表示最多跳得次数

输入输出样例

输入样例#1:

2 2
2 5
-1 3

输出样例#1:

2

说明

n,m<=100

这是二维DP样板,是DP中的豪杰,相较普通DP,思路和顺序也有些变化.

这题里,搜索函数是核心内容,建立数学模型也是比较重要(洛谷题解中有多种模型,构建不同也导致他们后续主函数运算部分难易不一,但其实不关键,能写出来就够了)

下面是我构建的搜索函数(疯狂膜洛谷题解大佬):

int sgs(int i,int j)
{
    int k=0;
    if(a[i][j]!=-1) return a[i][j];
    if(i-1>=1&&map[i-1][j]<map[i][j])
    {
        a[i][j]=max(a[i][j],sgs(i-1,j)+1);
        k=1;
    }
    if(j+1<=m&&map[i][j+1]<map[i][j])
    {
        a[i][j]=max(a[i][j],sgs(i,j+1)+1);
        k=1;
    }
    if(i+1<=n&&map[i+1][j]<map[i][j])
    {
        a[i][j]=max(a[i][j],sgs(i+1,j)+1);
        k=1;
    }
    if(j-1>=1&&map[i][j-1]<map[i][j])
    {
        a[i][j]=max(a[i][j],sgs(i,j-1)+1);
        k=1;
    }
    if(k==0) a[i][j]=0;
    return a[i][j];
 } 

其中map是储存地图数字的数组,a是储存"跳到这个格子的最大次数",对每一个点map[i,j]讨论跳到这个点所需的最大步数,再在主函数中forfor遍历全图就可以找到答案.

函数的查找方法是对该点的上下左右询问,看是否有比该点数字小的点,如果有比他小的(即可从那个点跳到该点),就拿a[i,j]和a[那个点]+1来取最大值.

其中值得注意的一行:

if(a[i][j]!=-1) return a[i][j];-1是在主函数中输入数据是赋值的.意为"未被询问的",被询问后就会有值(比大于0),依次区分,如果没有这行,那程序的运行会慢好多哦~~~以下是ac代码:
#include<iostream>
using namespace std;
int max(int a,int b)
{
	return a>b?a:b;
}
int map[101][101],a[101][101];
int n,m;
int sgs(int i,int j)
{
	int k=0;
	if(a[i][j]!=-1) return a[i][j];
	if(i-1>=1&&map[i-1][j]<map[i][j])
	{
		a[i][j]=max(a[i][j],sgs(i-1,j)+1);
		k=1;
	}
	if(j+1<=m&&map[i][j+1]<map[i][j])
	{
		a[i][j]=max(a[i][j],sgs(i,j+1)+1);
		k=1;
	}
	if(i+1<=n&&map[i+1][j]<map[i][j])
	{
		a[i][j]=max(a[i][j],sgs(i+1,j)+1);
		k=1;
	}
	if(j-1>=1&&map[i][j-1]<map[i][j])
	{
		a[i][j]=max(a[i][j],sgs(i,j-1)+1);
		k=1;
	}
	if(k==0) a[i][j]=0;
	return a[i][j];
 }
int main()
{
	int i,j,way=0;
	cin>>n>>m;
	for(i=1;i<=n;i++)
	for(j=1;j<=m;j++)
	{
		cin>>map[i][j];
		a[i][j]=-1;
	}
	for(i=1;i<=n;i++)
	for(j=1;j<=m;j++)
	way=max(way,sgs(i,j));
	cout<<way<<endl;
}

  注意边界的判断哦~(比心)

				
时间: 2024-08-03 19:20:22

洛谷p1732 活蹦乱跳的香穗子 二维DP的相关文章

洛谷 P1732 活蹦乱跳的香穗子

题目描述 香穗子在田野上调蘑菇!她跳啊跳,发现自己很无聊,于是她想了一个有趣的事情,每个格子最多只能经过1次,且每个格子都有其价值 跳的规则是这样的,香穗子可以向上下左右四个方向跳到相邻的格子,并且她只能往价值更高(这里是严格的大于)的格子跳. 香穗子可以从任意的格子出发,在任意的格子结束, 那么她最多能跳几次? 输入输出格式 输入格式: 第一行n,m,表示田野的长和宽 接下来n行,每行m个数,表示该格的价值 输出格式: 一个数,表示最多跳得次数 输入输出样例 输入样例#1: 2 2 2 5 -

P1732 活蹦乱跳的香穗子

题目描述 香穗子在田野上调蘑菇!她跳啊跳,发现自己很无聊,于是她想了一个有趣的事情,每个格子最多只能经过1次,且每个格子都有其价值 跳的规则是这样的,香穗子可以向上下左右四个方向跳到相邻的格子,并且她只能往价值更高(这里是严格的大于)的格子跳. 香穗子可以从任意的格子出发,在任意的格子结束, 那么她最多能跳几次? 输入输出格式 输入格式: 第一行n,m,表示田野的长和宽 接下来n行,每行m个数,表示该格的价值 输出格式: 一个数,表示最多跳得次数 输入输出样例 输入样例#1: 2 2 2 5 -

洛谷P1725 琪露诺 单调队列优化 DP

洛谷P1725 琪露诺 单调队列优化 DP 题意:1--n 每个点都有一个权值,从当前点i可以到达i+l--i+r 之间的点, 动态规划 方程 为 f[ i ] = max(f[ i ],f[ k ] ) +a[ i ] i-r<=k<=i-l 然而这样复杂度 就为 n^2 因为相当于 dp 是在求 一段区间的最大值,而这个最大值就可以用O(n) 来维护 注意 这个O(n) 是均摊O(n) 即将所有固定区间长度的 最大值求出来 是 O(n)的这样就把复杂度降到 O(n) 级别了 1 #incl

HDU 4901 The Romantic Hero(二维dp)

题目大意:给你n个数字,然后分成两份,前边的一份里面的元素进行异或,后面的一份里面的元素进行与.分的时候按照给的先后数序取数,后面的里面的所有的元素的下标一定比前面的大.问你有多上种放元素的方法可以使得前面异或的值和后面与的值相等. dp[x][y] 表示走到第x步,得到y这个数字一共有多少种方法. 但是需要注意这里得分一下,不能直接用dp数组存种数,你需要分一下从上一层过来的次数,和这一层自己可以到达的次数.然后取和的时候前后两个集合的种数进行乘法,注意边乘边取余. 顺便给一组数据: 4 3

二维dp(O(N^3)实现) zoj3230

1 #include<iostream> 2 #include<string.h> 3 #include<stdio.h> 4 #define maxn 125 5 using namespace std; 6 7 int cost[maxn][maxn],w[maxn][maxn]; 8 int dp[maxn][maxn]; 9 int N,M; 10 int main(){ 11 while(cin>>N>>M){ 12 if (N==0

hoj_10014_二维DP

The Triangle Time Limit: 1000ms, Special Time Limit:2000ms, Memory Limit:32768KB Total submit users: 952, Accepted users: 860 Problem 10014 : No special judgement Problem description 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 (Figure 1) Figure 1 shows a number tr

XTU1168:Alice and Bob(二维DP)

摘要:Dota(Defence of the Ancients,远古的守护), 是指基于魔兽争霸3:冰封王座(暴雪娱乐公司出品)的多人即时对战自定义地图,可支持10个人同时连线游戏.Dota以对立的两个小队展开对战,通常是5v5,游戏目的是守护自己的远古遗迹(近卫方的生命之树.天灾方的冰封王座),同时摧毁对方的远古遗迹.DotA是目前唯一被暴雪娱乐公司官方认可的魔兽争霸RPG.Dota在大学生中的风靡程度令人咂舌,而随着玩家对游戏的理解深入,本身存在于游戏中的许多数学模型被挖掘出来进行研究.游戏

HDU 5074 Hatsune Miku(简单二维dp)

题目大意:给你一些音符之间的联系,给你一个串,让你求出这个串的最大值.-1的时候可以任意替代,其他情况必须为序列上的数. 解题思路:简单二维dp,分情况处理就可以了啊. Hatsune Miku Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 637    Accepted Submission(s): 458 Problem De

(review)zoj4800 二维dp 状态转移很灵活

1 #include<iostream> 2 #include<stdio.h> 3 4 using namespace std; 5 6 double dp[10005][125]; 7 double p[125][125]; 8 int pk[10005]; 9 10 int N,M; 11 12 double fmax(double a,double b){ 13 if(a-b>0) return a;else return b; 14 } 15 int main(){