✪动态规划✪

最基础的注意重点:初始化+状态转移方程

非常基础的三角形求路径最大值https://www.luogu.com.cn/problem/P1216

#include<iostream>
using namespace std;

int r;
int dp[1001][1001];
 
int main(){
	cin>>r;
	for(int i=1;i<=r;i++)
		for(int j=1;j<=i;j++)
			cin>>dp[i][j];
	
	//初始化左右两斜线 
	for(int i=2;i<=r;i++){
		dp[i][1]+=dp[i-1][1];
		dp[i][i]+=dp[i-1][i-1];
	}
	
	for(int i=3;i<=r;i++){
		for(int j=2;j<i;j++){
			dp[i][j]+=max(dp[i-1][j-1],dp[i-1][j]);
		}
	} 
	
	int maxx=-1;
	
	for(int i=1;i<=r;i++)
		maxx=max(maxx,dp[r][i]);
	cout<<maxx;
}

大朋友的数字https://www.luogu.com.cn/problem/P2008

这道题涉及到的是求最长不下降子序列

这道题的思路是

因为每一个人的分数只由他前边的人决定,所以在一次遍历中可以完成输入数字+计算这个人的分数

num数组装数字,sum数组装分数

1,sum=1

2,j开始循环,1<2,dp[1]+1>dp[2],更新dp,sum=3

5,j开始循环,1<5,dp[1]+1>dp[5],更新dp,sum=6

                        2<5,dp[2]+1>dp[5],更新dp,sum=8

#include<iostream>
using namespace std;

int n;
int num[10000+10];	//每个人的数字 
int sum[10000+10];	//每个人的分数(到这里的最长不下降子序列的和) 
int dp[10000+10];	//dp[i]代表到第i个数它的最长子序列长度 

int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>num[i];
		sum[i]=num[i];
		for(int j=1;j<i;j++){
			if(num[j]<=num[i] && dp[j]+1>dp[i]){
				dp[i]=dp[j]+1;
				sum[i]=sum[j]+num[i];
			}
		}
		cout<<sum[i]<<" ";
	} 
}

又上锁妖塔https://www.luogu.com.cn/problem/P2800

 

自己写的:股票问题那学的思路 

#include<iostream>
using namespace std;

//n层
//每层的高度不同
int n;
int height[1000000+5]; 
//每次可以向上+1或+2
//跳完后必须至少一层
//理解题意,跳跃不花时间,爬楼的话消耗的就是高度的时间 
int dp[1000000+5][2];//到第i层时花费的最小时间 
//dp[i][0]代表第i层是跳上来的 
//dp[i][1]代表第i层是爬的 

int main(){
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>height[i];
		
	dp[1][0]=0;
	dp[1][1]=height[1];
	dp[2][0]=0;
	dp[2][1]=dp[1][0]+height[2];

	for(int i=3;i<=n;i++){
		//在每一层有两种选择,跳or爬 
		dp[i][0]=min(dp[i-1][1],dp[i-2][1]);
		dp[i][1]=height[i]+min(dp[i-1][1],dp[i-1][0]);
	}
	
	
	cout<<min(dp[n][0],dp[n][1]);

}

优秀的题解:

f[0]=0,因为底层不用爬

要求的是f[7]

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

int n;
int a[1000005];
int f[1000005];

int main() {
	cin>>n;
	for(int i=1; i<=n; i++) {
		cin>>a[i];
		f[i]=1e9;//注意初始化
	}
	f[n+1]=1e9;
	
	for(int i=1; i<=n+1; i++) {//循环到n+1
		f[i]=min(f[i],f[i-1]);
		f[i]=min(f[i],f[i-2]);
		f[i]=min(f[i],f[i-3]);
		f[i]+=a[i];
	}
	
	cout<<f[n+1];//输出解
	return 0;//愉快的结束
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值