2021-01-31 最大数字和

最大数字和

有一道题是这样的:
给出n个正整数,每次只能按顺序取出不相邻的数字,求出最大的数字和。

不废话直接给推论
在这里插入图片描述
这是 递归 的方法(小心爆内存 )。思路很简单。如果只能取不相邻数字,那么间隔一定为1或者2。当取到第n个时,上一个取的数字就是第n-2或n-3个。可以推出递归式

f(n) = max( f (n-2) , f (n-3) + arr[n] )

这里arr数组表示题目所给出的初始数据

还有另一种方法,也是我个人更喜欢的方法:建立状态转移方程
建立状态转移方程

方法类似,用0,1标注是否取到此点,从而递推得出答案,可以推出递归式

f (n, 0) = max( f (n-1, 0) ,f (n-1, 1))
f (n, 1) = f (n-1, 0) + arr [n]

完整代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#define N 10000001 
using namespace std;
typedef unsigned long long ull;

ull a[N], n, ans, f[N][3];

int main (){
	scanf("%d",&n);
	for(ull i=1; i<=n; i++){
		scanf("%d",&a[i]);
	}//读入 
	
	f[1][0]=0;f[1][1]=a[1];
	f[2][0]=a[1];f[2][1]=max(a[1],a[2]);
	//初始化部分数值 
	
	for(ull i=3; i<=n; i++){//第二种方法:状态转移方程 
		f[i][1] = f[i-1][0]+a[i];
		f[i][0] = max(f[i-1][0],f[i-1][1]);
	}
	
	ans = max(f[n][0],f[n][1]);
	
	printf("%lld",ans);//输出答案 

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值