题目背景

给定一个正整数序列a(1),a(2),...,a(n),(1<=n<=20)

不改变序列中每个元素在序列中的位置,把它们相加,并用括号记每次加法所得的和,称为中间和。

例如:

给出序列是4,1,2,3。

第一种添括号方法:

((4+1)+(2+3))=((5)+(5))=(10)

有三个中间和是5,5,10,它们之和为:5+5+10=20

第二种添括号方法

(4+((1+2)+3))=(4+((3)+3))=(4+(6))=(10)

中间和是3,6,10,它们之和为19。

题目描述

现在要添上n-1对括号,加法运算依括号顺序进行,得到n-1个中间和,求出使中间和之和最小的添括号方法。

输入输出格式

输入格式:

共两行。 第一行,为整数n。(1< =n< =20) 第二行,为a(1),a(2),...,a(n)这n个正整数,每个数字不超过100。

输出格式:

输出3行。 第一行,为添加括号的方法。 第二行,为最终的中间和之和。 第三行,为n-1个中间和,按照从里到外,从左到右的顺序输出。


一道很有价值的区间dp,一共包含了3个子问题;首先用区间dp求出f[i][j]及i-j之间最小的累加和,很显然有:

for(int len = ; len <= n; ++len) {
for(int l = ; l <= n - len + ; ++l) {
int r = l + len - ;
for(int i = l; i < r; ++i)
f[l][r] = min(f[l][r], f[l][i] + f[i + ][r]);
f[l][r] += sum[r] - sum[l - ];
}
}

接着用dfs枚举区间来求出括号的方案,同时求出所有区间的和,用ans作为序号便于输出,这样就A掉了,个别细节需要注意,切切切~~

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MAXN = 5e5 + ;
const int MAXM = 3e3 + ; inline int read() {
int x = , ff = ; char ch = getchar();
while(!isdigit(ch)) {
if(ch == '-') ff = -;
ch = getchar();
}
while(isdigit(ch)) {
x = (x << ) + (x << ) + (ch ^ );
ch = getchar();
}
return x * ff;
} inline void write(int x) {
if(x < ) putchar('-'), x = -x;
if(x > ) write(x / );
putchar(x % + '');
} int n, ans, a[MAXN], sum[MAXN], f[MAXM][MAXM];
priority_queue < pair < int, int > > q; void dfs(int l, int r) {
if(l == r) {
write(a[l]);
return ;
}
for(int i = r; i >= l; --i) { // 倒序,为了使方案等效时,以括弧靠左为优先~
if(f[l][i] + f[i + ][r] + sum[r] - sum[l - ] == f[l][r]) { // 好好思考~
putchar('(');
dfs(l, i);
putchar('+');
dfs(i + , r);
putchar(')');
q.push(make_pair(-(++ans), sum[r] - sum[l - ]));
return ;
}
}
} int main() {
memset(f, 0x3f, sizeof(f));
n = read();
for(int i = ; i <= n; ++i) {
a[i] = read();
f[i][i] = ;
sum[i] = sum[i - ] + a[i];
}
for(int len = ; len <= n; ++len) {
for(int l = ; l <= n - len + ; ++l) {
int r = l + len - ;
for(int i = l; i < r; ++i)
f[l][r] = min(f[l][r], f[l][i] + f[i + ][r]);
f[l][r] += sum[r] - sum[l - ];
}
}
dfs(, n);
putchar('\n');
write(f[][n]);
putchar('\n');
while(!q.empty()) {
int x = q.top().second; q.pop();
write(x);
putchar(' ');
}
return ;
}

P1291-添加括号(区间dp)的更多相关文章

  1. P2308 添加括号(区间DP)

    题目背景 给定一个正整数序列a(1),a(2),...,a(n),(1<=n<=20) 不改变序列中每个元素在序列中的位置,把它们相加,并用括号记每次加法所得的和,称为中间和. 例如: 给 ...

  2. TZOJ 3295 括号序列(区间DP)

    描述 给定一串字符串,只由 “[”.“]” .“(”.“)”四个字符构成.现在让你尽量少的添加括号,得到一个规则的序列. 例如:“()”.“[]”.“(())”.“([])”.“()[]”.“()[( ...

  3. 【区间DP】codevs3657 括号序列题解

    题目描述 Description 我们用以下规则定义一个合法的括号序列: (1)空序列是合法的 (2)假如S是一个合法的序列,则 (S) 和[S]都是合法的 (3)假如A 和 B 都是合法的,那么AB ...

  4. 括号序列(区间dp)

    括号序列(区间dp) 输入一个长度不超过100的,由"(",")","[",")"组成的序列,请添加尽量少的括号,得到一 ...

  5. 区间dp 括号匹配问题

    这道题目能用区间dp来解决,是因为一个大区间的括号匹配数是可以由小区间最优化选取得到(也就是满足最优子结构) 然后构造dp 既然是区间类型的dp 一般用二维 我们定义dp[i][j] 表示i~j这个区 ...

  6. UVA1626 括号序列 Brackets sequence(区间dp)

    题目传送门(洛谷)   题目传送门(UVA) 解题思路 很显然是一个区间dp,当然记忆化搜索完全可以AC,这里说一下区间dp. 区间dp的重要特征就是需要枚举中间节点k 看一看这道题,用f[i][j] ...

  7. 区间dp - 括号匹配并输出方案

    Let us define a regular brackets sequence in the following way: 1. Empty sequence is a regular seque ...

  8. poj2955括号匹配 区间DP

    Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5424   Accepted: 2909 Descript ...

  9. poj 2955 括号匹配 区间dp

    Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6033   Accepted: 3220 Descript ...

随机推荐

  1. make和rest用法

    位置(position):下一个要读取或写入的数据的索引.缓冲区的位置不能为负,并且不能大于其限制(limit). 标记(mark)与重置(reset):标记是一个索引,通过Buffer中的mark( ...

  2. PYTHON 爬虫笔记七:Selenium库基础用法

    知识点一:Selenium库详解及其基本使用 什么是Selenium selenium 是一套完整的web应用程序测试系统,包含了测试的录制(selenium IDE),编写及运行(Selenium ...

  3. POJ 2409 Let it Bead:置换群 Polya定理

    题目链接:http://poj.org/problem?id=2409 题意: 有一串n个珠子穿起来的项链,你有k种颜色来给每一个珠子染色. 问你染色后有多少种不同的项链. 注:“不同”的概念是指无论 ...

  4. 「洛谷 P1801」黑匣子

    好像很久没有更过博客了,因为博主这几周很忙.其实是在搞颓. 题意很难懂,所以就不重复了.其实是懒. 一眼看上去这是个 \(Splay\) 裸题,直接插入一个数,查询区间第 \(K\) 大,但是这样太不 ...

  5. 阿里巴巴fastjson源码阅读(待完成)

    git地址:https://github.com/alibaba/fastjson.git

  6. BaseServlet优化Servlet,实现类似struts2的一些简单效果

    package cn.itcast.web.servlet; import java.io.IOException; import javax.servlet.ServletException; im ...

  7. __declspec(dllimport)的小秘密(转)

    昨天和同事使用一个dll(lib+dll)的时候,发现他在引用头文件是,并没有使用__declspec(dllimport),但是程序完全运行正常,不明觉厉下,去网上翻了下资料,原来是链接器的原因,这 ...

  8. #基础概念#之tensor

    中译名:张量 定义: from wiki: In mathematics, tensors are geometric objects that describe linear relations b ...

  9. CardView以及RecycleView的一些问题

    下面这些属性在listview的标签里有用,在recyclerView里没用. tools:listitem="@layout/list_single_answer_item_borrowe ...

  10. bzoj3312

    K个硬币,要买N个物品. 给定买的顺序,即按顺序必须是一路买过去,当选定买的东西物品序列后,付出钱后,货主是不会找零钱的.现希望买完所需要的东西后,留下的钱越多越好,如果不能完成购买任务,输出-1 $ ...