P5154 数列游戏 [区间DP]

本文深入探讨了区间动态规划(DP)算法的实现细节,通过一个具体的问题实例,讲解了如何利用DP解决区间上的最优化问题。文章首先定义了状态dp[i]表示1到i的最优解,然后详细阐述了状态转移方程的推导过程,包括如何计算相邻区间的最大收益,以及如何通过子问题的最优解求解更大问题的最优解。最后,通过一个完整的C++代码示例,展示了区间DP算法的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门

先来一波区间DP的套路

f[l][r] = max(f[l][k]+f[k+1][r])

f[l][r] = max(f[l][r],f[l+1][r-1]+B[l]+B[r])(gcd(A[l],A[r]!=1))

记dp[i] 为1-i 的答案

dp[i]=max(dp[i-1],dp[j-1]+f[j][i])(1<=j<=i-1)


#include<bits/stdc++.h>
#define N 805
#define LL long long
#define inf 1000000000000000
using namespace std;
LL f[N][N], dp[N];
int A[N], B[N], n;
int read(){
	int cnt = 0; char ch = 0;
	while(!isdigit(ch)) ch = getchar();
	while(isdigit(ch)) cnt = cnt * 10 + (ch-'0'), ch = getchar();
	return cnt; 
}
int gcd(int a,int b){ return !b ? a : gcd(b, a%b);}
int main(){
	n = read();
	for(int i=1;i<=n;i++) A[i] = read();
	for(int i=1;i<=n;i++) B[i] = read();
	for(int i=1;i<n;i++) f[i][i+1] = (gcd(A[i],A[i+1])!=1) ? (B[i]+B[i+1]) : -inf;
	for(int len=4;len<=n;len+=2){
		for(int l=1;l<=n-len+1;l++){
			int r = l+len-1; f[l][r] = -inf;
			if(gcd(A[l], A[r]) != 1) f[l][r] = f[l+1][r-1] + B[l] + B[r];
			for(int k=l+1;k<r;k+=2) f[l][r] = max(f[l][r], f[l][k] + f[k+1][r]);
		}
	}
	for(int i=2;i<=n;i++){ 
		dp[i] = dp[i-1];
		for(int j=1;j<=i-1;j++)
			dp[i] = max(dp[i], dp[j-1] + f[j][i]);
	}
	printf("%lld",dp[n]); return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

FSYo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值