您的位置:首页 > 其它

HDU5900 QSC and Master(区间DP)2016 ACM/ICPC Asia Regional Shenyang Online

2016-09-19 23:20 363 查看
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5900


QSC and Master

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Total Submission(s): 747    Accepted Submission(s): 275


Problem Description

Every school has some legends, Northeastern University is the same.

Enter from the north gate of Northeastern University,You are facing the main building of Northeastern University.Ninety-nine percent of the students have not been there,It is said that there is a monster in it.

QSCI am a curious NEU_ACMer,This is the story he told us.

It’s a certain period,QSCI am in a dark night, secretly sneaked into the East Building,hope to see the master.After a serious search,He finally saw the little master in a dark corner. The master said:

“You and I, we're interfacing.please solve my little puzzle!

There are N pairs of numbers,Each pair consists of a key and a value,Now you need to move out some of the pairs to get the score.You can move out two continuous pairs,if and only if their keys are non coprime(their gcd is not one).The final score you get is
the sum of all pair’s value which be moved out. May I ask how many points you can get the most?

The answer you give is directly related to your final exam results~The young man~”

QSC is very sad when he told the story,He failed his linear algebra that year because he didn't work out the puzzle.

Could you solve this puzzle?

(Data range:1<=N<=300

1<=Ai.key<=1,000,000,000

0<Ai.value<=1,000,000,000)

 

Input

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.

 

Output

For each test case,output the max score you could get in a line.

 

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

题目大意:给出n pair 数,每pair数key和val表示当前这pair数的键值和权值,现在可以将相邻的两个数i,i+1合并,如果满足gcd(a[i],a[i+1])>1,得到的价值是两个数的权值和,每次合并两个数之后,这两个数就会消失,然后旁边的数会补上。

如:1 2 3 4,2跟3合并后就消失,剩下1 4,然后1和4又可以合并。

解题思路:典型区间DP问题,

dp[i][j]表示区间[i,j]获得的权值最大值,所以有转移方程:

d[i][j] = max(d[i][j], d[i][k] + d[k + 1][j]) 

然后要考虑的一种情况是,可以把中间的数合并后再合并两边的能获得最大值,

如3 8 4 9,先合并8和4,再合并3和9.

所以有转移方程:dp[i][j] = max(dp[i][j],dp[i+1][j-1]+a[i].second+a[j].second)

但是要注意的是要实现这个必须保证中间的先全部消去并且是最大值。

/* ***********************************************
┆  ┏┓   ┏┓ ┆
┆┏┛┻━━━┛┻┓ ┆
┆┃       ┃ ┆
┆┃   ━   ┃ ┆
┆┃ ┳┛ ┗┳ ┃ ┆
┆┃       ┃ ┆
┆┃   ┻   ┃ ┆
┆┗━┓ 马 ┏━┛ ┆
┆  ┃ 勒 ┃  ┆      
┆  ┃ 戈 ┗━━━┓ ┆
┆  ┃ 壁     ┣┓┆
┆  ┃ 的草泥马  ┏┛┆
┆  ┗┓┓┏━┳┓┏┛ ┆
┆   ┃┫┫ ┃┫┫ ┆
┆   ┗┻┛ ┗┻┛ ┆
************************************************ */

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <bitset>
using namespace std;

#define rep(i,a,b) for (int i=(a),_ed=(b);i<=_ed;i++)
#define per(i,a,b) for (int i=(b),_ed=(a);i>=_ed;i--)
#define pb push_back
#define mp make_pair
const int inf_int = 2e9;
const long long inf_ll = 2e18;
#define inf_add 0x3f3f3f3f
#define mod 1000000007
#define LL long long
#define ULL unsigned long long
#define MS0(X) memset((X), 0, sizeof((X)))
#define SelfType LL
SelfType Gcd(SelfType p,SelfType q){return q==0?p:Gcd(q,p%q);}
SelfType Pow(SelfType p,SelfType q){SelfType ans=1;while(q){if(q&1)ans=ans*p;p=p*p;q>>=1;}return ans;}
#define Sd(X) int (X); scanf("%d", &X)
#define Sdd(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define Sddd(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define reunique(v) v.resize(std::unique(v.begin(), v.end()) - v.begin())
#define all(a) a.begin(), a.end()
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef vector<int> vi;
typedef vector<long long> vll;
inline int read(){int ra,fh;char rx;rx=getchar(),ra=0,fh=1;while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();if(rx=='-')fh=-1,rx=getchar();while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh;}
//#pragma comment(linker, "/STACK:102400000,102400000")

pll a[305];
LL dp[305][305], pre[305];
int n;

LL solve()
{
for(int len=1;len<n;len++)
{
for(int i=1;i<=n && i+len<=n;i++)
{
int j = i + len;
for(int k=i;k<j;k++)
dp[i][j] = max(dp[i][j],dp[i][k]+dp[k+1][j]);
if(Gcd(a[i].first,a[j].first)>1)
{
if(len==1) dp[i][j] = max(dp[i][j],a[i].second+a[j].second);
else if(dp[i+1][j-1]==pre[j-1]-pre[i])
{
dp[i][j] = max(dp[i][j],dp[i+1][j-1]+a[i].second+a[j].second);
}
}
}
}
return dp[1]
;
}

int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
int t;
t = read();
while(t--)
{
n = read();
for(int i=1;i<=n;i++)
{
scanf("%I64d",&a[i].first);
}
for(int i=1;i<=n;i++)
{
scanf("%I64d",&a[i].second);
pre[i] = pre[i-1] + a[i].second;
}
MS0(dp);
printf("%I64d\n",solve());
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐