dp(数塔2084+免费馅饼1176+最长回文子串)

本文深入解析了数塔问题、免费馅饼问题及最长回文子串等经典动态规划(DP)问题,通过实例代码详细阐述了从下至上计算最优解的策略,适合初学者掌握DP核心思想。

数塔问题
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2084
数塔问题是很典型的dp问题。
该题大概的思路为:
因为从上往下算的话只知道局部最大,但局部最大不能保证整体最大,则需要从下往上面推。
具体看图:
在这里插入图片描述
假设这时在倒数第二层,那么可以根据下一层算出这层每个放歌的最大值,接着是倒数第三层,依次往上推,就可以获得最大值。

公式为:
a[i][j] = max(a[i+1][j]+a[i][j],a[i+1][j+1]+a[i][j]);

#include <bits/stdc++.h>
using namespace std;
int a[105][105];
int main(){
	int tcase;
	cin>>tcase;
	while(tcase--){
		int N;
		cin>>N;
		for(int i=1;i<=N;i++){
			for(int j = 1;j<=i;j++){
				cin>>a[i][j];
			}
		}
		//开始DP
		for(int i = N-1;i>=1;i--){//倒数第二行开始计算 
			for(int j =1;j<=i;j++){
				a[i][j] = max(a[i+1][j]+a[i][j],a[i+1][j+1]+a[i][j]);//求出最大 
			} 
		}
		 cout<<a[1][1]<<endl;
	}
	return 0;
}

免费馅饼:
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1176
在这里插入图片描述
思路与数塔思路相似,都是采用dp思想,从下往上不断计算,直到算出最上层的每个空格的最大值,然后输出起点dp[0][5]的值即可。

公式为:
dp[i][j] = max(max(dp[i+1][j]+dp[i][j],dp[i+1][j-1]+dp[i][j]),dp[i+1][j+1]+dp[i][j]);

(没太注意输入结束的条件,并且又忘记了初始化二维数组和c值)。

#include <bits/stdc++.h>
using namespace std;
int dp[100010][12];
int c;
int main(){
	int n,x,t;
	while(cin>>n && n != 0){
		c = 0;
		memset(dp,0,sizeof(dp));
		while(n--){
		cin>>x>>t;
		if(t>=c){
			c = t;
		}
		dp[t][x]++;//每个位置同一时间的个数
	  }
	//开始dp 
	for(int i = c-1;i>=0;i--){
		for(int j = 0;j<=10;j++){
			dp[i][j] = max(max(dp[i+1][j]+dp[i][j],dp[i+1][j-1]+dp[i][j]),dp[i+1][j+1]+dp[i][j]);
		}
	}
	cout<<dp[0][5]<<endl;
   }
  return 0;
}

最长回文子串

首先弄清楚子串是连续的,回文子串就是从前往后和从后往前读都是一样的。
(一开始总是搞不清楚,今晚感觉看懂了就赶紧写一下)
①首先一个字符肯定是回文子串所以先设置a[i][i] = true;
②用一个dp[i][j],表示从i到j是否是回文子串,每一次判断dp[i][j]是否是回文子串,就先判断dp[i+1][j-1]是否是,如果不是,那就flase,否则为true。怎么实现就是用两个for循环,外层表示子串的尾,内层表示子串的头。
需要注意当 i == j时就是一个为true;而当i+1==j的时候,他俩相邻,中间没有子串,所以直接判断。
③边找边判断max 的ans

#include <bits/stdc++.h>
using namespace std;
bool dp[1010][1010];
int ans = 1;
int main(){
	string a;
	cin>>a;
	memset(dp,0,sizeof(dp));
	for(int i =0;i<1010;i++){
		dp[i][i] = true;
	}
	for(int j = 0;j < a.length();j++){
		for(int i = 0;i <= j;i++){
			if(i==j) continue;
			if(j==i+1) {if(a[i]==a[j]) dp[i][j] = true; continue;}
			if(a[i] == a[j] && dp[i+1][j-1]){
				dp[i][j] = true;
				ans = max(ans,j-i+1);
			}
		}
	}
	cout<<"最长回文子串长度为:"<<ans<<endl;
	return 0;
}
内容概要:本文介绍了基于贝叶斯优化的CNN-LSTM混合神经网络在时间序列预测中的应用,并提供了完整的Matlab代码实现。该模型结合了卷积神经网络(CNN)在特征提取方面的优势与长短期记忆网络(LSTM)在处理时序依赖问题上的强大能力,形成一种高效的混合预测架构。通过贝叶斯优化算法自动调参,提升了模型的预测精度与泛化能力,适用于风电、光伏、负荷、交通流等多种复杂非线性系统的预测任务。文中还展示了模型训练流程、参数优化机制及实际预测效果分析,突出其在科研与工程应用中的实用性。; 适合人群:具备一定机器学习基基于贝叶斯优化CNN-LSTM混合神经网络预测(Matlab代码实现)础和Matlab编程经验的高校研究生、科研人员及从事预测建模的工程技术人员,尤其适合关注深度学习与智能优化算法结合应用的研究者。; 使用场景及目标:①解决各类时间序列预测问题,如能源出力预测、电力负荷预测、环境数据预测等;②学习如何将CNN-LSTM模型与贝叶斯优化相结合,提升模型性能;③掌握Matlab环境下深度学习模型搭建与超参数自动优化的技术路线。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,重点关注贝叶斯优化模块与混合神经网络结构的设计逻辑,通过调整数据集和参数加深对模型工作机制的理解,同时可将其框架迁移至其他预测场景中验证效果。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值