题目链接   http://acm.hdu.edu.cn/showproblem.php?pid=5900

题意:给出序列$A_{i}.key$和$A_{i}.value$,若当前相邻的两个数$A_{i}.key$和$A_{i+1}.key$的最大公约数大于1,则可以把这两个数消去,同时消去$A_{i}.value$和$A_{i+1}.value$,每次消去得到的分数为$A_{i}$和$A_{i+1}$的value值,问最大可能得分。

注意:当$A_{i}$和$A_{i+1}被$消去后,$A_{i-1}$和$A_{i+2}$成为了新的相邻的数。若符合条件则可以继续消去。

思路:很明显是区间DP,但是我比赛中如何也A不了。原因有两个:1.没有注意到位运算的低优先级。2.没有把所有情况考虑清楚。

设$f[i][j]$为从第$i$个数到第$j$个数所能得到的最大得分,$j-i+1$从2开始依次枚举,最后枚举到$f[1][n]$(考虑DP的无后效性)

分类讨论即可。先考虑不合并的情况,则$f[i][j]$被$f[i][k]+f[k + 1][j]$依次更新。

          再考虑合并的情况$f[i][j]$可以被$f[i][k] + a[k + 1] + a[k + 2] + f[k +3][j]$更新。

          特殊情况讨论:当$a[i + 1]$到$a[j - 1]$中所有的数都可以被消去,则$a[i]$和$a[j]$作为相邻的数也可以被消去。这种情况的讨论非常重要!!!

      代码送上

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional> using namespace std; #define REP(i,n) for(int i(0); i < (n); ++i)
#define rep(i,a,b) for(int i(a); i <= (b); ++i)
#define dec(i,a,b) for(int i(a); i >= (b); --i)
#define for_edge(i,x) for(int i = H[x]; i; i = X[i]) const int N = + ;
const int M = + ;
const int Q = + ;
const int A = + ; typedef long long LL; LL f[Q][Q];
bool c[Q][Q];
bool ret[Q][Q];
int T;
int n;
LL a[Q], b[Q];
LL gcd(LL a, LL b){ return b == ? a : gcd(b, a % b); } int main(){
scanf("%d", &T);
while (T--){
scanf("%d", &n);
memset(a, , sizeof a);
memset(b, , sizeof b);
memset(c, false, sizeof c);
memset(ret, false, sizeof ret);
memset(f, , sizeof f);
rep(i, , n) scanf("%lld", a + i);
rep(i, , n) scanf("%lld", b + i);
rep(i, , n - ) rep(j, i + , n) if (gcd(a[i], a[j]) != ) c[i][j] = true;
rep(i, , n - ) if (gcd(a[i], a[i + ]) > ) ret[i][i + ] = true;
for (int len = ; len <= n; len += ){
rep(i, , n - len + ){
int j = i + len - ;
bool flag = false;
if (c[i][i + ] && ret[i + ][j]) flag = true;
if (c[j - ][j] && ret[i][j - ]) flag = true;
if (c[i][j] && ret[i + ][j - ]) flag = true;
for (int k = i + ; k <= j - ; k += ) if (ret[k][k + ] && ret[i][k - ] && ret[k + ][j]){ flag = true; break;}
if (flag) ret[i][j] = true;
}
} rep(i, , n - ) if (c[i][i + ]) f[i][i + ] = b[i] + b[i + ];
rep(i, , n - ) f[i][i + ] = max(f[i][i + ], f[i + ][i + ]);
rep(len, , n){
rep(i, , n - len + ){
int j = i + len - ;
rep(k, i, j) f[i][j] = max(f[i][j], f[i][k] + f[k + ][j]);
if (len % == ){ if (ret[i + ][j - ] && c[i][j]) f[i][j] = max(f[i][j], b[i] + b[j] + f[i + ][j - ]); }
f[i][j] = max(f[i][j], f[i + ][j]);
f[i][j] = max(f[i][j], f[i][j - ]);
if (c[i][i + ]) f[i][j] = max(f[i][i + ] + f[i + ][j], f[i][j]);
if (c[j - ][j]) f[i][j] = max(f[j - ][j] + f[i][j - ], f[i][j]);
rep(k, i + , j - ) if (c[k][k + ]) f[i][j] = max(f[i][j], f[i][k - ] + f[k][k + ] + f[k + ][j]);
}
}
printf("%lld\n", f[][n]); } return ; }

HDU 5900 QSC and Master (区间DP)的更多相关文章

  1. HDU 5900 QSC and Master 区间DP

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

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

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

  3. HDU 5900 QSC and Master

    题目链接:传送门 题目大意:长度为n的key数组与value数组,若相邻的key互斥,则可以删去这两个数同时获得对应的两 个value值,问最多能获得多少 题目思路:区间DP 闲谈: 这个题一开始没有 ...

  4. HDU 5900 - QSC and Master [ DP ]

    题意: 给n件物品,有key和value 每次可以把相邻的 GCD(key[i], key[i+1]) != 1 的两件物品,问移除的物品的总value最多是多少 key : 1 3 4 2  移除3 ...

  5. hdu 4597 + uva 10891(一类区间dp)

    题目链接:http://vjudge.net/problem/viewProblem.action?id=19461 思路:一类经典的博弈类区间dp,我们令dp[l][r]表示玩家A从区间[l, r] ...

  6. HDU 2476 String painter (区间DP)

    题意:给出两个串a和b,一次只能将一个区间刷一次,问最少几次能让a=b 思路:首先考虑最坏的情况,就是先将一个空白字符串刷成b需要的次数,直接区间DP[i][j]表示i到j的最小次数. 再考虑把a变成 ...

  7. hdu_5900_QSC and Master(区间DP)

    题目链接:hdu_5900_QSC and Master 题意: 有n个数,每个数有个key值,有个val,如果相邻的两个数的key的gcd大于1那么就可以得到这两个数的val的和,现在问怎么取使得到 ...

  8. HDU 4597 Play Game(区间DP(记忆化搜索))

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4597 题目大意: 有两行卡片,每个卡片都有各自的权值. 两个人轮流取卡片,每次只能从任一行的左端或右端 ...

  9. HDU 5151 Sit sit sit 区间DP + 排列组合

    Sit sit sit 问题描述 在一个XX大学中有NN张椅子排成一排,椅子上都没有人,每张椅子都有颜色,分别为蓝色或者红色. 接下来依次来了NN个学生,标号依次为1,2,3,...,N. 对于每个学 ...

随机推荐

  1. super和final关键字

    一.super关键字 super关键字的使用 JAVA类中使用super来引用父类的属性或者方法,用this来引用当前对象,主要用法: 1.子类的构造函数默认第一行会默认调用父类的无参数构造函数 2. ...

  2. jquery实现各种实例

    1.正反选实例 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  3. 用archlinux作为日常开发机的感受

    机器配置 CPU: Intel Core i5-6200U RAM: 8G Resolution: 1920x1080 我在arch下常用的软件 图形桌面环境 i3wm wifi无线管理 Networ ...

  4. 【Android】实验6 在应用程序中播放音频和视频 截止提交报告时间2016.4.21

    注:也可以在数独游戏项目中完成该实验的内容.

  5. hadoop2.5.2学习及实践笔记(六)—— Hadoop文件系统及其java接口

    文件系统概述 org.apache.hadoop.fs.FileSystem是hadoop的抽象文件系统,为不同的数据访问提供了统一的接口,并提供了大量具体文件系统的实现,满足hadoop上各种数据访 ...

  6. Java中类的继承深入剖析

    在Java开发中,我们常常用到继承这一概念,可以说继承是Java这类面向对象编程语言的基石.正是有了继承这个概念,使得我们可以创建分等级层次的类.今天小编就和大家一起来深入聊聊Java语言的继承. 在 ...

  7. P2507 [SCOI2008]配对

    题目背景 四川NOI2008省选 题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配对. ...

  8. Custom LDAP Monitor Does Not Work

    Custom LDAP Monitor Does Not Work https://www.poppelgaard.com/netscaler-case-study-custom-ldap-monit ...

  9. BZOJ 4326 NOIP2015 运输计划(树上差分+LCA+二分答案)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MB Submit: 1388  Solved: 860 [Submit][Stat ...

  10. BZOJ2599 [IOI2011]Race 【点分治】

    题目 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 输入格式 第一行 两个整数 n, k 第二..n行 每行三个整 ...