HDU 5900 QSC and Master

题目链接:传送门

题目大意:长度为n的key数组与value数组,若相邻的key互斥,则可以删去这两个数同时获得对应的两

     个value值,问最多能获得多少

题目思路:区间DP

闲谈:  这个题一开始没有做出来,找了下原因,是自己思维太局限(刷题太少),始终想怎样去维护相

     邻这个条件,删去数之后怎么来拼接左右两段。。。最后导致没解出来。。

正解:  其实维护拼接我们可以用一个数组来实现,先预处理原数组中相邻的两个数,然后再利用区间

     DP思想来进行扩展,最后根据这个预处理好的数组来实现判断与更新。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cctype>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <climits>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define fi first
#define se second
#define ping(x,y) ((x-y)*(x-y))
#define mst(x,y) memset(x,y,sizeof(x))
#define mcp(x,y) memcpy(x,y,sizeof(y))
using namespace std;
#define gamma 0.5772156649015328606065120
#define MOD 1000000007
#define inf 0x3f3f3f3f
#define N 1000050
#define maxn 3001
typedef pair<int,int> PII;
typedef long long LL;

int n,m;
int key[500],va[500];
LL sum[500];
int ok[500][500];
LL dp[500][500];
LL ans;
LL read(){
    LL x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return x*f;
}
void init(){
    mst(ok,0);
    for(int i=2;i<=n;++i)ok[i-1][i]=__gcd(key[i],key[i-1])==1?0:1;
    for(int l=3;l<=n;++l)
    for(int i=1;i+l-1<=n;++i){
        int j=i+l-1; 
        ok[i][j]=(ok[i+1][j-1]&&__gcd(key[i],key[j])!=1);
        for(int k=i;k<j;++k)
            ok[i][j]+=(ok[i][k]&&ok[k+1][j]);
    }
}
void solve(){
    mst(dp,0);
    for(int l=2;l<=n;++l)
    for(int i=1;i+l-1<=n;++i){
        int j=i+l-1; 
        if(ok[i][j]) dp[i][j]=sum[j]-sum[i-1];
        else{
            for(int k=i;k<j;++k){
                dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]);
            }
        }
    }
    printf("%lld\n",dp[1][n]);
}
int main(){
    int i,j,group;
    group=read();
    while(group--){
        scanf("%d",&n);
        for(i=1;i<=n;++i) key[i]=read();
        for(j=1;j<=n;++j) va[j]=read(),sum[j]=sum[j-1]+va[j];
        init();
        solve();
    }
    return 0;
}

 

posted @ 2016-09-21 14:34  Kurokey  阅读(215)  评论(0编辑  收藏  举报