HDU 5900 QSC and Master(区间DP)

15 篇文章 1 订阅

Description

给出 n n 个数对(keyi,vali),对于相邻的两个数对,如果它们的键值不互素则可以同时拿走这两个数对,得分为其价值之和,问最多可以得多少分

Input

第一行一整数 T T 表示用例组数,每组用例首先输入一整数n表示数对的个数,之后输入 n n 个整数keyi表示每个数对的键值,最后输入 n n 个整数vali表示每个数对的价值

(1T10,1n300,1keyi109,0vali109) ( 1 ≤ T ≤ 10 , 1 ≤ n ≤ 300 , 1 ≤ k e y i ≤ 10 9 , 0 ≤ v a l i ≤ 10 9 )

Output

输出最大得分

Sample Input

3
3
1 2 3
1 1 1
3
1 2 4
1 1 1
4
1 3 4 3
1 1 1 1

Sample Output

0
2
0

Solution

区间 DP D P ,以 dp[l][r] d p [ l ] [ r ] 表示从第 l l 个数对到第r个数对可以拿到的最大得分,有两种方案,要么把该区间分成两部分分别考虑,要么就是第 l+1 l + 1 个数对到第 r1 r − 1 个数对全部被拿走且 gcd(keyl,keyr)>1 g c d ( k e y l , k e y r ) > 1 ,这样第 l l 个数对和第r个数对可以凑一起拿走,为快速判断是否可以将区间 [l+1,r1] [ l + 1 , r − 1 ] 的数对全部拿走,对价值求前缀和 sumi=j=1ivalj s u m i = ∑ j = 1 i v a l j ,如果 dp[l+1][r1]=sumr1suml d p [ l + 1 ] [ r − 1 ] = s u m r − 1 − s u m l 则说明区间 [l+1,r1] [ l + 1 , r − 1 ] 可以全部被拿走,以此求出 dp[1][n] d p [ 1 ] [ n ] 即为答案,时间复杂度 O(Tn3) O ( T n 3 )

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
#define maxn 333
int T,n,a[maxn],v[maxn];
ll sum[maxn],dp[maxn][maxn];
int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}
ll dfs(int l,int r)
{
    if(dp[l][r]!=-1)return dp[l][r];
    ll ans=-1;
    if(l==r)ans=0;
    else if(r==l+1)
    {
        if(gcd(a[l],a[r])>1)ans=v[l]+v[r];
        else ans=0;
    }
    else 
    {
        int temp=gcd(a[l],a[r]);
        if(temp!=1&&dfs(l+1,r-1)==sum[r-1]-sum[l])ans=sum[r]-sum[l-1];
        for(int i=l;i<r;i++)ans=max(ans,dfs(l,i)+dfs(i+1,r));
    }
    return dp[l][r]=ans;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        memset(dp,-1,sizeof(dp));
        scanf("%d",&n);
        sum[0]=0;
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)scanf("%d",&v[i]),sum[i]=sum[i-1]+v[i];
        printf("%I64d\n",dfs(1,n));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值