题意:

给你一个长为300的序列,每个位置有个代号和价值

如果相邻两个位置的代号不互质就可以得到他们的价值和并移除他们

问最大价值

思路:

区间dp,n才100,直接n*3就可以

/* ***********************************************
Author        :devil
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
#define inf 0x3f3f3f3f
#define LL long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ou(a) printf("%d\n",a)
#define pb push_back
#define mkp make_pair
template<class T>inline void rd(T &x){char c=getchar();x=0;while(!isdigit(c))c=getchar();while(isdigit(c)){x=x*10+c-'0';c=getchar();}}
#define IN freopen("in.txt","r",stdin);
#define OUT freopen("out.txt","w",stdout);
using namespace std;
const int mod=1e9+7;
const int N=310;
int a[N];
LL b[N],dp[N][N],sum[N];
int main()
{
    int t,n;
    rd(t);
    while(t--)
    {
        rd(n);
        rep(i,1,n) rd(a[i]);
        rep(i,1,n) rd(b[i]),sum[i]=sum[i-1]+b[i];
        rep(i,1,n-1) dp[i][i+1]=__gcd(a[i],a[i+1])==1?0:b[i]+b[i+1];
        rep(l,2,n-1) rep(i,1,n-l)
        {
            int j=i+l;
            if(__gcd(a[i],a[j])!=1&&dp[i+1][j-1]==sum[j-1]-sum[i]){dp[i][j]=sum[j]-sum[i-1];continue;}
            dp[i][j]=dp[i+1][j];
            rep(k,i+1,j-1) dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]);
        }
        printf("%lld\n",dp[1][n]);
    }
    return 0;
}