hdu5900

题目

只有相邻不互质的才能加和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;
}

猜你喜欢

转载自blog.csdn.net/soul_97/article/details/81155555