HDU 5900 QSC and Master (区间DP)
题目链接 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)的更多相关文章
- HDU 5900 QSC and Master 区间DP
QSC and Master Problem Description Every school has some legends, Northeastern University is the s ...
- 2016 年沈阳网络赛---QSC and Master(区间DP)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5900 Problem Description Every school has some legend ...
- HDU 5900 QSC and Master
题目链接:传送门 题目大意:长度为n的key数组与value数组,若相邻的key互斥,则可以删去这两个数同时获得对应的两 个value值,问最多能获得多少 题目思路:区间DP 闲谈: 这个题一开始没有 ...
- HDU 5900 - QSC and Master [ DP ]
题意: 给n件物品,有key和value 每次可以把相邻的 GCD(key[i], key[i+1]) != 1 的两件物品,问移除的物品的总value最多是多少 key : 1 3 4 2 移除3 ...
- hdu 4597 + uva 10891(一类区间dp)
题目链接:http://vjudge.net/problem/viewProblem.action?id=19461 思路:一类经典的博弈类区间dp,我们令dp[l][r]表示玩家A从区间[l, r] ...
- HDU 2476 String painter (区间DP)
题意:给出两个串a和b,一次只能将一个区间刷一次,问最少几次能让a=b 思路:首先考虑最坏的情况,就是先将一个空白字符串刷成b需要的次数,直接区间DP[i][j]表示i到j的最小次数. 再考虑把a变成 ...
- hdu_5900_QSC and Master(区间DP)
题目链接:hdu_5900_QSC and Master 题意: 有n个数,每个数有个key值,有个val,如果相邻的两个数的key的gcd大于1那么就可以得到这两个数的val的和,现在问怎么取使得到 ...
- HDU 4597 Play Game(区间DP(记忆化搜索))
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4597 题目大意: 有两行卡片,每个卡片都有各自的权值. 两个人轮流取卡片,每次只能从任一行的左端或右端 ...
- HDU 5151 Sit sit sit 区间DP + 排列组合
Sit sit sit 问题描述 在一个XX大学中有NN张椅子排成一排,椅子上都没有人,每张椅子都有颜色,分别为蓝色或者红色. 接下来依次来了NN个学生,标号依次为1,2,3,...,N. 对于每个学 ...
随机推荐
- 《Cracking the Coding Interview》——第8章:面向对象设计——题目1
2014-04-23 17:32 题目:请设计一个数据结构来模拟一副牌,你要如何用这副牌玩21点呢? 解法:说实话,扑克牌的花样在于各种花色.顺子.连对.三带一.炸弹等等,如果能设计一个数据结构,让判 ...
- Object Pascal中文手册 经典教程
Object Pascal 参考手册 (Ver 0.1)ezdelphi@hotmail.com OverviewOverview(概述)Using object pascal(使用 object p ...
- 天性 & 如水一般,遇强则强 —— 梦想、行为、性格
开篇声明,我博客中“小心情”这一系列,全都是日记啊随笔啊什么乱七八糟的.如果一不小心点进来了,不妨直接关掉.我自己曾经写过一段时间的日记,常常翻看,毫无疑问我的文笔是很差的,而且心情也是瞬息万变的.因 ...
- SpringMVC 集成 Freemarker 模板引擎
本文通过 maven 项目中集成 1.引入 SpringMVC 与 Freemarker 需要的依赖 <!-- SpringMVC --> <dependency> <g ...
- springboot相关链接
springboot的三种启动方式 https://blog.csdn.net/my__Sun_/article/details/72866329 springboot学历历程 https://www ...
- NGUI-为Popuplist的下拉选项添加删除功能
NGUI例子里的popuplist是这样的:,但有时我们希望下拉选项都有删除功能,也就是这样:,一种方法是改popuplist的源码,我想这个实现起来不难,但现在我想说的是用反射来实现此功能,以及其他 ...
- MySQL数据库有哪些特点
MySQL数据库的特点有: 它是C和C++语言编写的.支持多个操作系统.支持多线程.为多种编程语言提供API.优化SQL算法提高了查询速度以及提供用于管理和检查数据库的管理工具 MySQL数据库 My ...
- Virtual box 虚拟机 不可使用的一种解决方法
在win7下开着一个ubuntu虚拟机,写了好几小时代码,然后饿了,去吃点东西 回来发现,电脑由于win7 自动更新已经重启 ubuntu下的代码我已经走开时保存过了,所以不怎么担心 但是打开virt ...
- Oracle 数据库导出时 EXP-00008;ORA-00904
问题是客户端和服务器端版本问题,我本地是11g,而服务器端是10g. 规则1:低版本的exp/imp可以连接到高版本(或同版本)的数据库服务器,但高版本的exp/imp不能连接到低版本的数据库服务器. ...
- HTML5的JavaScript选择器介绍
在HTML5出现之前使用JavaScript查找DOM元素,有以下三种原生的方法: getElementById:根据指定元素的id属性返回元素 getElementsByName:返回所有指定nam ...