课程记录——数字三角形

这节课讲的dp。真的是dp啦.;w;

一、题目描述

【题目名称、来源】

 数字三角形  ioi94-1

【问题描述】

数字三角形

                7

               3 8

              8 1 0

             2 7 4 4

            4 5 2 6 5

             (图3.1-1)

  (图3.1-1)示出了一个数字三角形。 请编一个程序计算从顶至底的某处的一条路

径,使该路径所经过的数字的总和最大。

 ●每一步可沿左斜线向下或右斜线向下走;

 ●1<三角形行数≤100;

 ●三角形中的数字为整数0,1,…99;

输入数据:

由INPUT.TXT文件中首先读到的是三角形的行数。

在例子中INPUT.TXT表示如下:

5

7

3 8

8 1 0

2 7 4 4

4 5 2 6 5

输出数据:

把最大总和(整数)写入OUTPUT.TXT文件。

上例为:

30

 2 3

4 5 6

变成了

1

2 3

4 5 6

三、方法和代码

1、dfs(递归)

#include<iostream>
#include<cstdio>




using namespace std;


const int N=107;
int a[N][N];
int ans;
int n;

//定义函数dfs
void dfs(int i,int j,int sum)
{
	if(i==n)//是否到出口 
	{
		if(sum>ans)ans=sum;
		//到出口了 
		return;
	}
	//没到出口,继续dps 
	dfs(i+1,j,sum+a[i+1][j]);
	dfs(i+1,j+1,sum+a[i+1][j+1]);
}




int main()
{
	cin>>n;
	
	//读入数据,存入数组 
	for(int i=1;i<=n;i++)
	{
		for(int j=1;i<=i;j++)
		{
			cin>>a[i][j];
		}
	}
	
	//进行dfs 
	dfs(1,1,a[1][1]);
	
	//输出答案
	cout<<ans<<endl; 
	
	return 0;
}

小结

太慢,重复,不好用。太大,longlong存不下。

递归:重复的子问题,慢。

——————————————————————————————————————————

——————————————————————————————————————————

改进->记录曾经走过的路,如果一样就不走了。

用表记录子问题的解,以后可以直接用。有明显的阶段性

——————————————————————————————————————————

——————————————————————————————————————————

2、记忆化搜索/计划搜索(dp思想)

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

const int N=107;
int a[N][N],f[N][N]; 
int n;

//定义函数dfs 
void dfs(int i,int j,int sum)
{
	if(i==n)//是否到出口 
	{
		f[i][j]=a[i][j];
		//到出口了 
		return;
	}
	if(f[i+1][j]==-1)//这个位置如果没搜过,进行搜索。否则不搜索。 
	dfs(i+1,j,sum+a[i+1][j]);
	if(f[i+1][j+1]==-1)//这个位置如果没搜过,进行搜索。否则不搜索。 
	dfs(i+1,j+1,sum+a[i+1][j+1]);
	
	f[i][j]= a[i][j] + f[i+1][j]>f[i+1][j+1] ? f[i+1][j]:f[i+1][j+1];//更新从本身向下走的最大和 
}


int main()
{
	memset(f,-1,sizeof(f));//数据初始化,全都没搜过 
	cin>>n;
	
	//读入数据,存入数组 
	for(int i=1;i<=n;i++)
	{
		for(int j=1;i<=i;j++)
		{
			cin>>a[i][j];
		}
	}
	
	f[1][1]=a[1][1];
	
	//进行dfs 
	dfs(1,1,a[1][1]);
	
	//输出答案
	cout<<f[1][1]<<endl; 
	
	return 0;
}
 
 

3、倒推和顺推

倒推: f[i][j]=max(f[i+1][j],f[i+1][j+1])+a[i][j]

从下向上加,记录最大的。


顺推同理。

灵魂画手哈哈哈哈哈哈

四、我再说两句话,就两句话

1.

分析递归,写出来用递推。

dp可以看作递推的一种。(弗洛伊德算法也算啊)

2.

dp,多阶段决策问题,搞笑高效。

经常拿来做最短路径问题。不过只用于拥有明显阶段性*的那种,否则还是该迪杰斯特拉迪杰斯特拉,弗洛伊德弗洛伊德。

不会打英文名显得好low哦

*明显的阶段性,就是你别走回头路。别a都到d了突然出现一条路能从d到a。

3.

dp就多做题吧......多做题就懂了。qwq

洛谷上啦都有模版题。

4.

这节课讲的是坐标型dp,下节课讲线性型dp。(就是周六。现在是18/4/18。)

net。shiyan。cn

oier,123456

猜你喜欢

转载自blog.csdn.net/lateknife/article/details/79993007