2023.7.25

#I. 数字三角形1

Description

给出一个数字三角形,你从[1,1]开始出发,走到最后一行。每次站在一个点上时,可以向下走,或者向右下走。将经过的数字加起来,希望其和最大。

7

3 8

8 1 0

2 7 4 4

4 5 2 6 5

Format

Input

第一行给出数字N

接下来N行描述这个数字三角形,所给出的数字为100以内的正整数。

N<=100

Output

如题

Samples

输入数据 1

5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

输出数据 1

30

递归

可加记忆化优化

​

#include<bits/stdc++.h>
using namespace std;
int n,v[110][110],ex[110][110];//记忆化,ex[i][j]代表从(1,1)走到(i,j)的最大代价 
int ans;
int walk(int x,int y)
{
	if(x==1&&y==1)//出口:已知(1,1)到(1,1)的代价 
		return v[1][1];
	if(ex[x][y]==0)
		if(y==1)//注意过界 
			ex[x][y]=v[x][y]+walk(x-1,y);
		else	
			if(x==y)//注意过界 
				ex[x][y]=v[x][y]+walk(x-1,y-1);	
			else
				ex[x][y]=v[x][y]+max(walk(x-1,y-1),walk(x-1,y));		
	return ex[x][y];
}	
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=i;j++)
			scanf("%d",&v[i][j]);//代价 
	for(int i=1;i<=n;i++)
		walk(n,i);
	for(int i=1;i<=n;i++)
		ans=max(ans,ex[n][i]);//最大代价 
	printf("%d",ans);		
	return 0;		
}

[点击并拖拽以移动]
​

 

#include<bits/stdc++.h>
using namespace std;
int n,v[110][110],ex[110][110];//记忆化,ex[i][j]代表从(i,j)走到第n行的最大代价 
int walk(int x,int y)
{
	if(x==n)
		return v[x][y];//出口:从第n行到第n行代价已知 
	if(ex[x][y]==0)
		ex[x][y]=v[x][y]+max(walk(x+1,y),walk(x+1,y+1));
	return ex[x][y];	 
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=i;j++)
			scanf("%d",&v[i][j]);//代价 
	printf("%d",walk(1,1));
	return 0;		
}

#J. 马的遍历

Description

中国象棋大家都玩过吧!!!

现在有只小马迷路了,它现在在左下角的(0,0)位置,它的家在右上角的(m,n)位置

(棋盘大小为m*n)

现规定小马只能往右走,请聪明的你帮帮小马算一下回到家有几种方案?

注意:

(0,0)点在左下角,(m,n)在右上角,

棋盘内所有点的坐标(x,y)

满足x>=0&&x<=m&&y>=0&&y<=n

Format

Input

家的位置m,n

1=<m,n<=30

Output

一个整数即方案数

Samples

【输入样例】

输入数据 1

4 8

输出数据 1

37

递归+记忆化

注意:涉及有边界的位移,调用数组前要判断是否出界

#include<bits/stdc++.h>
using namespace std;
int n,m,v[34][34];
int missin(int x,int y)
{
	if(x==m&&y==n)
	{
		v[x][y]=1;
		return 1;
	}
	if(x<0||y<0||x>m||y>n)
		return 0;
	if(v[x][y])
		return v[x][y]; 
	v[x][y]=missin(x+1,y+2)+missin(x-1,y+2)+missin(x+2,y+1)+missin(x-2,y+1);
	return v[x][y];	
}
int main()
{
	memset(v,0,sizeof(v));
	scanf("%d %d",&m,&n);
	printf("%d",missin(0,0));
	return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值