0
点赞
收藏
分享

微信扫一扫

P5154 数列游戏 [区间DP]

木樨点点 2022-07-12 阅读 43

​​传送门​​

先来一波区间DP的套路

P5154 数列游戏 [区间DP]_#define

P5154 数列游戏 [区间DP]_git_02

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

P5154 数列游戏 [区间DP]_git_03

#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;
}

 


举报

相关推荐

0 条评论