题目

Source

http://acm.hdu.edu.cn/showproblem.php?pid=5900

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个<key,value>二元组,每次可以取出相邻的且其key的GCD不为1的两个二元组,并获得二者value之和的价值,问能取到的最大价值是多少?

注意取掉后就左右两部分就合并在一起。。
显然考虑区间DP:

  • dp[i][j]表示下标i到j的二元组全部消除能获得的最大价值
  • 通过枚举k(i<=k<j)从max(dp[i][k]+dp[k+1][j])转移;此外如果key[i]等于key[j],还能从dp[i+1][j-1]+value[i]+value[j]转移

于是这样就能求出所有能消除的全部区间以及消除它们能获得的最大价值,而问题就是要从这些区间取出不重叠的几个使得价值和最大。
这个可以用最小费用最大流解,区间k覆盖。。也能再dp一次,dp[i]表示考虑坐标点在i之前的区间所能获得的最大价值。。

代码

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<queue>
  4. #include<algorithm>
  5. using namespace std;
  6. #define INF (1LL<<60)
  7. #define MAXN 333
  8. #define MAXM 3333*666
  9. struct Edge{
  10. int u,v,next;
  11. long long cap,cost;
  12. }edge[MAXM];
  13. int head[MAXN];
  14. int NV,NE,vs,vt;
  15.  
  16. void addEdge(int u,int v,long long cap,long long cost){
  17. edge[NE].u=u; edge[NE].v=v; edge[NE].cap=cap; edge[NE].cost=cost;
  18. edge[NE].next=head[u]; head[u]=NE++;
  19. edge[NE].u=v; edge[NE].v=u; edge[NE].cap=0; edge[NE].cost=-cost;
  20. edge[NE].next=head[v]; head[v]=NE++;
  21. }
  22. bool vis[MAXN];
  23. long long dis[MAXN];
  24. int pre[MAXN];
  25. bool SPFA(){
  26. for(int i=0; i<NV; ++i){
  27. vis[i]=0;
  28. dis[i]=INF;
  29. }
  30. vis[vs]=1;
  31. dis[vs]=0;
  32. queue<int> que;
  33. que.push(vs);
  34. while(!que.empty()){
  35. int u=que.front(); que.pop();
  36. for(int i=head[u]; i!=-1; i=edge[i].next){
  37. int v=edge[i].v;
  38. if(edge[i].cap && dis[v]>dis[u]+edge[i].cost){
  39. dis[v]=dis[u]+edge[i].cost;
  40. pre[v]=i;
  41. if(!vis[v]){
  42. vis[v]=1;
  43. que.push(v);
  44. }
  45. }
  46. }
  47. vis[u]=0;
  48. }
  49. return dis[vt]!=INF;
  50. }
  51. long long MCMF(){
  52. long long res=0;
  53. while(SPFA()){
  54. long long flow=INF,cost=0;
  55. for(int u=vt; u!=vs; u=edge[pre[u]].u){
  56. flow=min(flow,edge[pre[u]].cap);
  57. }
  58. for(int u=vt; u!=vs; u=edge[pre[u]].u){
  59. edge[pre[u]].cap-=flow;
  60. edge[pre[u]^1].cap+=flow;
  61. cost+=flow*edge[pre[u]].cost;
  62. }
  63. res+=cost;
  64. }
  65. return res;
  66. }
  67.  
  68. long long d[MAXN][MAXN];
  69.  
  70. long long gcd(long long a,long long b){
  71. if(b==0) return a;
  72. return gcd(b,a%b);
  73. }
  74.  
  75. bool ok[MAXN][MAXN];
  76.  
  77. long long key[MAXN],val[MAXN];
  78.  
  79. int main(){
  80. int t,n;
  81. scanf("%d",&t);
  82. while(t--){
  83. scanf("%d",&n);
  84. for(int i=1; i<=n; ++i){
  85. scanf("%I64d",key+i);
  86. }
  87. for(int i=1; i<=n; ++i){
  88. scanf("%I64d",val+i);
  89. }
  90. memset(ok,0,sizeof(ok));
  91. for(int i=1; i<=n; ++i){
  92. for(int j=i+1; j<=n; ++j){
  93. if(gcd(key[i],key[j])==1) continue;
  94. ok[i][j]=1;
  95. ok[j][i]=1;
  96. }
  97. }
  98. for(int i=1; i<=n; ++i){
  99. for(int j=1; j<=n; ++j){
  100. d[i][j]=-INF;
  101. }
  102. }
  103. for(int len=2; len<=n; ++len){
  104. for(int i=1; i+len-1<=n; ++i){
  105. if(ok[i][i+len-1] && len==2){
  106. d[i][i+len-1]=val[i]+val[i+len-1];
  107. continue;
  108. }
  109. if(ok[i][i+len-1]) d[i][i+len-1]=max(d[i][i+len-1],val[i]+val[i+len-1]+d[i+1][i+len-1-1]);
  110. for(int j=0; j<len-1; ++j){
  111. d[i][i+len-1]=max(d[i][i+len-1],d[i][i+j]+d[i+j+1][i+len-1]);
  112. }
  113. }
  114. }
  115. long long ans=0;
  116.  
  117. vs=0; vt=n+2; NV=vt+1; NE=0;
  118. memset(head,-1,sizeof(head));
  119. addEdge(vs,1,1,0);
  120. addEdge(n+1,vt,1,0);
  121. for(int i=1; i<=n; ++i){
  122. addEdge(i,i+1,INF,0);
  123. }
  124. for(int i=1; i<=n; ++i){
  125. for(int j=i+1; j<=n; ++j){
  126. if(d[i][j]!=-INF){
  127. addEdge(i,j+1,1,-d[i][j]);
  128. }
  129. }
  130. }
  131. printf("%I64d\n",-MCMF());
  132. }
  133. }

HDU5900 QSC and Master(区间DP + 最小费用最大流)的更多相关文章

  1. 2016 年沈阳网络赛---QSC and Master(区间DP)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5900 Problem Description Every school has some legend ...

  2. HDU 5900 QSC and Master 区间DP

    QSC and Master Problem Description   Every school has some legends, Northeastern University is the s ...

  3. hdu4106 区间k覆盖问题(连续m个数,最多选k个数) 最小费用最大流 建图巧妙

    /** 题目:hdu4106 区间k覆盖问题(连续m个数,最多选k个数) 最小费用最大流 建图巧妙 链接:http://acm.hdu.edu.cn/showproblem.php?pid=4106 ...

  4. poj3680 Intervals 区间k覆盖问题 最小费用最大流 建图巧妙

    /** 题目:poj3680 Intervals 区间k覆盖问题 最小费用最大流 建图巧妙 链接:http://poj.org/problem?id=3680 题意:给定n个区间,每个区间(ai,bi ...

  5. 51Nod 1084 矩阵取数问题 V2 —— 最小费用最大流 or 多线程DP

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1084 1084 矩阵取数问题 V2  基准时间限制:2 秒 空 ...

  6. ZOJ3762 The Bonus Salary!(最小费用最大流)

    题意:给你N个的任务一定要在每天的[Li,Ri]时段完成,然后你只有K天的时间,每个任务有个val,然后求K天里能够获得的最大bonus. 思路:拿到手第一直觉是最小费用最大流,然后不会建图,就跑去想 ...

  7. hdu 2686 Matrix 最小费用最大流

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2686 Yifenfei very like play a number game in the n*n ...

  8. HDU - 6437 Problem L.Videos 2018 Multi-University Training Contest 10 (最小费用最大流)

    题意:M个影片,其属性有开始时间S,结束时间T,类型op和权值val.有K个人,每个人可以看若干个时间不相交的影片,其获得的收益是这个影片的权值val,但如果观看的影片相邻为相同的属性,那么收益要减少 ...

  9. BZOJ 1221: [HNOI2001] 软件开发【最小费用最大流】

    Description 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员 ...

随机推荐

  1. SDL 1.2.15 issue

    SDL 1.2.15中,对于X11的函数,默认采用动态加载的方式 但相应的X11函数名在SDL中并没有重新命名(SDL2中都添加了前缀X11_) 这样在SDL与其他库混合静态编译链接时,X11的函数就 ...

  2. 通用PE工具箱 4.0精简优化版

    通用PE工具箱 4.0精简优化版 经用过不少 WinPE 系统,都不是很满意,普遍存在篡改主页.添加广告链接至收藏夹.未经允许安装推广软件等流氓行为,还集成了诸多不常用的工具,令人头疼不已.那么今天给 ...

  3. yuv420转rgb 及 rgb转bmp保存

    /// <summary> /// 将一桢 YUV 格式的图像转换为一桢 RGB 格式图像. /// </summary> /// <param name="y ...

  4. css 实现三角形 实现过程

     1.纯色的全等的三角形实现 下面的就是实际实现  没有宽高 只有边框 都是透明 根据箭头的方向 给边框方法加颜色  比如需要像右箭头 只需要给border-right-color:颜色值; 即可 c ...

  5. log4net各种Filter使用【转】

    log4net各种Filter使用[转] log4net里面的filter类常用的为:      1.DenyAllFilter         拒绝所用的日志输出         <filte ...

  6. PHP代码编写规范

    一. 变量命名 a) 所有字母都使用小写 b) 首字母根据变量值类型指定 i. 整数i ii. 浮点数f iii. 字符串s iv. 布尔值b v. 数组a vi. 对象o vii. 资源r viii ...

  7. Android Killer工具用法

    一.工程信息 工程信息主要是解析的AndroidManifest文件 二.工程管理器 三.配置插入代码 在代码中点右键就可以一键插入代码了 四.字符串搜索功能 支持正则, 比jeb搜索功能强大 来自为 ...

  8. dynamic和var的区别

    1.var声明一个局部变量只是一种简化语法,它要求编译器根据一个表达式推断具体的数据类型. 2.var只能用于声明方法内部的局部变量,而dynamic可用于局部变量,字段,参数. 3.表达式不能转型为 ...

  9. poj 并查集

    http://poj.org/problem?id=1611 水题 题意:就是找一共有多少个人感染了,0是感染学生的编号. #include <stdio.h> #include < ...

  10. Java实现JDBC连接数据库实例

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sq ...