刷题日记 day7

本文探讨了两种重要的算法——动态规划(DP)和深度优先搜索(DFS),并结合具体题目进行讲解。首先解释了如何在不知道如何使用DP时通过多维数组实现记忆化搜索。接着分析了在设置DP数组时为何要在最大值后加1的原因。然后,文章转向另一题目,涉及树的直径计算,强调了数据类型和邻接表在处理这类问题时的重要性。两道题目展示了DP和DFS在解决实际问题中的应用。
摘要由CSDN通过智能技术生成

地宫去取宝 (搜索  + DP + 记忆化)

这个题一开始知道方法  但是不知道这个过程要怎么处理  其实在不知道怎么使用dp的时候 可以将dp的数组设置成一个多维的变量  从而再这个过程中  达到这个效果 

这个题还是有一点不懂的就是  在设置这个数组的得时候为什么一直要在max的后面加1   一时还不知道在这里是为什么?下次在深搜的时候客户以注意一下

#include<bits/stdc++.h>
using namespace std;
int dp[55][55][15][15];
int mp[55][55];
int n,m,k;
const int mod = 1000000007;
int dfs(int x,int y,int num,int max)
{
	if(dp[x][y][num][max] != -1)
	{
		return dp[x][y][num][max+1];
	}
	if(x == n&&y == m)
	{
		if(num == k||(num == k-1&&max<mp[x][y]))
			return dp[x][y][num][max+1] =1;
			else
		return dp[x][y][num][max+1] =0;
	}
	//截止条件写完之后
	long int s =0;
	if(x+1<=n)
	{
		//可以取  这样代码写的就 很简单 
		if(max < mp[x][y]) 
			s+=dfs(x+1,y,num+1,mp[x][y]);//才可以取
		s+=dfs(x+1,y,num,max);//不取 
	 } 
	 if(y+1<=m)
	 {
	 	if(max < mp[x][y]) 
			s+=dfs(x,y+1,num+1,mp[x][y]);//才可以取
		s+=dfs(x,y+1,num,max);//不取 
	  } 
	  return dp[x][y][num][max+1] = s%mod;
}
int main()
{
	cin>>n>>m>>k;
	for(int i = 1;i<=n;i++)
	{
		for(int j =1;j<=m;j++)
			cin>>mp[i][j];
	}
	memset(dp,-1,sizeof(dp));
	dfs(1,1,0,-1);
	cout<<dp[1][1][0][0]<<endl;//那这里为什么要从0开始 
	return 0;
}

大臣的旅费 这一题其实也不难  主要是进行一个求树的直径即可   很简单  但是这一题需要考虑的是数据类型的范围  所以在这里就不适合用数组来写  应当开一个领接表来试一试,

#include<bits/stdc++.h>
using namespace std;
int mp[10000][10000];
bool vis[10000];
int n;
int ans = 0;
int maxn =0;
void dfs(int x)
{
	bool flag =1;
	for(int i =1;i<=n;i++)
	{
		if(vis[i] == 0&&mp[x][i]!=0)
		{//只要进入了这一步 就相当于是可以再进入下一步了  也就是这里不再 
			flag = 0;
			vis[i] = 1;
			ans+=mp[x][i];
			dfs(i);
			ans-=mp[x][i];
			vis[i] = 0;
		}
	}
	if(flag == 1)
		maxn = max(maxn,ans);
}
int main()
{
	memset(vis,0,sizeof(vis));
	memset(mp,0,sizeof(mp));
	cin>>n;
	for(int i =0;i<n-1;i++)
	{
		int x,y,w;
		cin>>x>>y>>w;
		mp[x][y] = w;
		mp[y][x] = w;
	}
	//值已经 
	int maxnum = 0;
	for(int i =1;i<=n;i++)
	{
		ans = 0;
		vis[i] = 1;
		dfs(i);//代表从i开始的距离 
		vis[i] = 0;
		maxnum = max(maxn,maxnum);
	}
	//cout<<maxnum<<endl;
	long long int count =0;
	for(int i = 1;i<=maxnum;i++)
	{
		count+=10+i;
	}
	cout<<count<<endl;
	return 0;
}

这里先贴上矩阵。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值