翻过DP这座大山

本文介绍了在解决AcWing跳台阶问题中,如何使用暴力搜索(深度优先搜索)、记忆化搜索以及递推方法进行优化,以提高代码效率。通过实例展示了从DFS到记忆化搜索再到状态转移方程的解决方案过程。
摘要由CSDN通过智能技术生成

1.AcWing 跳台阶

第一种方法:暴力搜索DFS
在这里插入图片描述

#include <iostream>
using namespace std;

int dfs(int n)
{
	if(n == 1) return 1;
	else if(n == 2) return 2;
	else return dfs(n-1)+dfs(n-2);
}

int main()
{
	int x; cin>>x;
	
	cout<<dfs(x)<<endl;
	
	return 0;
}

显然如果数据范围大一点的话 就过不了 !!! 所以拿出我们的神器------>记忆化搜索

第二种方法:记忆化搜索

#include <iostream>
using namespace std;

const int N = 10000;

int mem[N],t;

int dfs(int n)
{
	if(mem[n]) return mem[n];
	
	int sum = 0;
	
	if(n == 1) sum = 1;
	else if(n == 2) sum = 2;
	else sum =  dfs(n-1)+dfs(n-2);
	
	mem[n] = sum;
	return sum;
}

int main()
{
	int t; cin>>t;
	
	cout<<dfs(t)<<endl;
	
	return 0;
}

第三种:递推

#include <iostream>
using namespace std;

const int N = 40;

int f[N],n;

int main()
{
	f[1] = 1,f[2] = 2;
	cin>>n;
	
	if(n == 1 || n == 2)
	{
		cout<<f[n]<<endl;
		return 0;
	}
	
	for(int i=3;i<=n;i++)
	{
		f[i] = f[i-1]+f[i-2];
	}
	
	cout<<f[n]<<endl;
		
	return 0;
}

2.Dotcpp 题目 3067: 大盗阿福

记忆化搜索

#include <bits/stdc++.h>
using namespace std;

const int N = 111111;

int t,n,p[N],mem[N];

int dfs(int x)
{
	if(mem[x]) return mem[x];
	
	int sum = 0;
	if(x>n) sum=0;
	else sum = max(dfs(x+1),dfs(x+2)+p[x]);	
	
	mem[x] = sum;
	return sum;
}

int main()
{
	scanf("%d",&t);
	
	while(t--)
	{
		scanf("%d",&n);
		
		for(int i=1;i<=n;i++) scanf("%d",&p[i]);
		memset(mem,0,sizeof mem);
		
		
		int cnt = dfs(1);
		
		printf("%d\n",cnt);
	}
		
	return 0;
}

改为递推:
状态转移方程为:f[i] = max(f[i+1], f[i+2] + p[i])
在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;

const int N = 111111;

int t,n,p[N],f[N];

int main()
{
	scanf("%d",&t);
	
	while(t--)
	{
		scanf("%d",&n);
		
		for(int i=1;i<=n;i++) scanf("%d",&p[i]);
		
		memset(f,0,sizeof f);
		for(int i=n;i>=1;i--)
		{
			f[i] = max(f[i+1],f[i+2]+p[i]);
			// 逆序遍历数组p,计算f数组的值。  
            // f[i]表示从第i个数开始,取若干个连续的数(至少一个),使得这些数的和最大。  
            // 状态转移方程为:f[i] = max(f[i+1], f[i+2] + p[i])  
            // 这里的思路是考虑当前位置i是否取数,如果取数,则下一个位置i+1不能取数,因此考虑f[i+2] + p[i]。
		}
		
		printf("%d\n",f[1]);
	}
	
	return 0;
}

继续空间优化: !!! 待续


2.数字三角形!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

像linux的企鹅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值