题解: 我们可以先通过dp判断哪些可以进行合并然后再通过一维dp 得到最大值
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#define ll long long
using namespace std;
const int maxn = 505;
ll d[maxn] = {0};
bool dp[maxn][maxn] = {0};
ll a[maxn] = {0};
ll b[maxn] = {0};
ll sum[maxn] = {0};
ll ans = 0;
int main () {
ios_base :: sync_with_stdio(false);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
memset (d,0,sizeof (d));
memset (dp,0,sizeof (dp));
memset (sum,0,sizeof (sum));
for (int i = 1;i <= n; ++ i) cin >> a[i];
for (int i = 1;i <= n; ++ i){
cin >> b[i];
sum[i] += b[i];
sum[i] += sum[i - 1];
}
for (int i = 1;i < n; ++ i) {
if (__gcd(a[i],a[i + 1]) != 1) {
dp[i][i + 1] = 1;
}
}
for (int l = 3;l <= n; l += 2) {
for (int i = 1;i + l <= n; ++i) {
int j = i + l;
for (int k = i + 1;k < j; ++ k) {
if (dp[i][k] && dp[k + 1][j]) {
dp[i][j] = 1;
}
}
if (__gcd(a[i],a[j]) != 1 && dp[i + 1][j - 1]) {
dp[i][j] = 1;
}
}
}
for (int i = 1;i <= n; ++ i) {
d[i] = d[i - 1];
for (int j = 1;j < i; ++ j) {
if (dp[j][i]) {
d[i] = max (d[i],d[j - 1] + sum[i] - sum[j - 1]);
}
}
}
// cout << dp[1][n] << endl;
cout << d[n] << endl;
}
return 0;
}