只有相邻不互质的才能加和value
我们可以提前做一个前缀和 方便求任何区间的value加和
枚举割点K时 dp[i][j] = max(dp[i][j], dp[i][k] + dp[k+1][j]); 加和转换方程
就是把两个区间结果相加
如果i j 互质的结果不为1 则咱判断他们是否相邻 或者是否可以直接相加和value
if(gcd(k[i],k[j]) > 1)
{
if(i + 1 == j) dp[i][j] = v[i] + v[j];
else if(dp[i+1][j-1] == sum[j - 1] - sum[i]) dp[i][j] = max(dp[i][j], dp[i +1][j-1] +v[i] +v[j]);
}
如果相邻 则 dp[i][j] = v[i] + v[j];
不相邻时 可以判断 他们直接的区间是否都为两两不互质的 如果是 可以将端点的value进行加和
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
typedef long long ll;
const int maxn = 305;
ll k[maxn],v[maxn], sum[maxn],dp[maxn][maxn];
int n;
ll gcd(ll a,ll b)
{
return b == 0? a : gcd(b, a % b);
}
int main()
{
int t;
cin >> t;
while(t --)
{
cin >> n;
memset(dp,0,sizeof(dp));
sum[0] = 0;
for(int i = 1;i <= n;i ++)
cin >> k[i];
for(int i = 1;i <= n;i ++)
cin >> v[i],sum[i] = sum[i-1] + v[i];
for(int len = 1;len <= n;len ++)
{
for(int i = 1;i <= n - len + 1;i ++)
{
int j = i + len - 1;
for(int k = i;k < j;k ++)
dp[i][j] = max(dp[i][j], dp[i][k] + dp[k+1][j]);
if(gcd(k[i],k[j]) > 1)
{
if(i + 1 == j) dp[i][j] = v[i] + v[j];
else if(dp[i+1][j-1] == sum[j - 1] - sum[i]) dp[i][j] = max(dp[i][j], dp[i +1][j-1] +v[i] +v[j]);
}
}
}
cout << dp[1][n] << endl;
}
return 0;
}