HDU 5900 QSC and Master 区间dp
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5900
QSC and Master
Memory Limit: 131072/131072 K (Java/Others)
First line contains a integer T,means there are T(1≤T≤10) test case。
Each test case start with one integer N . Next line contains N integers,means Ai.key.Next line contains N integers,means Ai.value.
输出
For each test case,output the max score you could get in a line.
样例输入
3
3
1 2 3
1 1 1
3
1 2 4
1 1 1
4
1 3 4 3
1 1 1 1
样例输出
0
2
0
题意
给你若干个数,如果相邻的两个数不互质,那么就可以吧它们消掉,并且取得这两个数的权值,问如何消能过获得最大的权值和。
题解
区间dp,dp[i][j]表示区间[i,j]能够获得的最大权值的方案,这里有个贪心策略,如果能全部消掉,我们肯定选择全部消。
代码
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf
typedef __int64 LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;
const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0);
//start----------------------------------------------------------------------
const int maxn=333;
LL arr[maxn],sumv[maxn],val[maxn];
LL dp[maxn][maxn];
LL gcd(LL a,LL b){
return b==0?a:gcd(b,a%b);
}
LL dfs(int l,int r){
if(dp[l][r]>=0) return dp[l][r];
if(l==r) return dp[l][r]=0;
if(l==r-1){
if(gcd(arr[l],arr[r])==1) return dp[l][r]=0;
else return dp[l][r]=val[l]+val[r];
}
LL &res=dp[l][r]=0;
for(int k=l;k<r;k++){
res=max(res,dfs(l,k)+dfs(k+1,r));
}
LL tmp=dfs(l+1,r-1);
if(tmp==sumv[r-1]-sumv[l]&&gcd(arr[l],arr[r])!=1) res=max(res,tmp+val[l]+val[r]);
else res=max(res,tmp);
return res;
}
void init(){
clr(dp,-1);
}
int n;
int main() {
int tc,kase=0;
scf("%d",&tc);
while(tc--){
init();
scf("%d",&n);
for(int i=1;i<=n;i++) scf("%I64d",&arr[i]);
for(int i=1;i<=n;i++) scf("%I64d",&val[i]);
sumv[0]=0;
for(int i=1;i<=n;i++) sumv[i]=sumv[i-1]+val[i];
prf("%I64d\n",dfs(1,n));
}
return 0;
}
//end-----------------------------------------------------------------------