题目背景

给定一个正整数序列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个中间和,按照从里到外,从左到右的顺序输出。

输入输出样例

输入样例#1:

4
4 1 2 3
输出样例#1:

(4+((1+2)+3))
19
3 6 10 题解:第二问的答案其实就是合并石头,dp(i,j)表示i到j 合并后的最小值。
首先需要用sum[i]预处理sum[j]-sum[i-1]表示区间的合并和;
dp(i,j) = min(dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1])
k表示枚举的断点,i<=k<j;

重点就是第一问和第三问。

对于这两问可以一起求。

用一个 dfs 从[1,n] 这个状态往回推每次找到一个 x 表示 当前 [l,r] 状态是用 [l,x] 和 [x+1,r] 转移而来的。

然后对于第一问,可以这样考虑,记录一个 numL[i] 表示 i 作为 l 被递归了几次。由题目的观察可以发现,i 作为 l 被递归的次数(除 l=r=i的情况时) 就是 i 前面(与 i 相连)的左括号数。

类似的,记录一个numR[i] 表示 i 作为 r 被递归了几次。还是由题目的观察可以发现,i 作为 r 被递归的次数(除 l=r=i的情况时) 就是 i 后面的(与 i 相连)右括号数。

当然 如果numL[i]≠0 则 numR[i]=0  因为除去了 l=r=i 的情况时。

然后在输出的时候 对于每一个数前面输出 numL[i] 个‘(’   后面输出numR[i] 个‘)’    然后在两个数之间加 ‘+’字符即可。

对于第二问,由于是dfs将[1,n]状态进行分割,所以就是在回溯时,直接记录 sum[l,r] 就好辣。

然后就愉快的AC了


#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
int kr[],pa[][],a[],kl[],g[][],dp[][],sum[];
void dfs(int x , int y)
{
if(x==y)
return ;
kl[x]++;
kr[y]++;
dfs(x,g[x][y]);
dfs(g[x][y]+,y);
}
void DFS(int x , int y)
{
if(x==y)
return ;
DFS(x,g[x][y]);
DFS(g[x][y]+,y);
cout<<sum[y]-sum[x-]<<' ';
}
int main()
{
int n;
scanf("%d",&n);
for(int i= ; i<=n ; i++)
{
scanf("%d",&a[i]);
sum[i]=sum[i-]+a[i];
dp[i][i]=;
}
for(int i=n- ; i ; i--)
{
for(int j=i+ ; j<=n ; j++)
{
dp[i][j]=1e9;
for(int k=i ; k<j ; k++)
{
if(dp[i][j]>=dp[i][k] + dp[k+][j] + sum[j] - sum[i-])
{
dp[i][j]=dp[i][k] + dp[k+][j] + sum[j] - sum[i-];
g[i][j]=k;
}
}
}
}
dfs(,n);
for(int i= ; i<=n ; i++)
{
for(int j= ; j<=kl[i] ; j++)
cout<<'(';
cout<<a[i];
if(!kr[i]&&i!=n)
cout<<'+';
for(int j= ; j<=kr[i] ; j++)
cout<<')';
if(kr[i]&&i!=n)
cout<<'+';
}
cout<<endl;
cout<<dp[][n]<<endl;
DFS(,n);
}

 

P2308 添加括号(区间DP)的更多相关文章

  1. P2308 添加括号

    P2308 添加括号 题解 一看这题---我能AC 看完这题---我要换题 这题第二问其实就是一个链的石子合并,也就是不用处理环 所以一三问怎么处理??? 数组 mid[ i ][ j ] 记录区间 ...

  2. P2308 添加括号(dfs记录dp路径)

    传送门 \(一看肯定是区间DP(因为和和合并石子很相似,都要加n-1次)\) \(转移方程为(其中he[i][j]是i到j的和)\) \[dp[i][j]=min(dp[i][j],dp[i][k]+ ...

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

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

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

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

  5. 括号序列(区间dp)

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

  6. P1291-添加括号(区间dp)

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

  7. 区间dp 括号匹配问题

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

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

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

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

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

随机推荐

  1. NYOJ-115 Dijlstra

    原题链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=115 #include"iostream" #include" ...

  2. 文件系统(node.js学习笔记)

    根据nodejs菜鸟教程整理. 官方API文档:nodeJS文件系统API 其他整理:nodejs File System 文件系统操作函数分类 1.引用: 导入文件系统模块(fs)语句:var fs ...

  3. bzoj 2178 圆的面积并 —— 辛普森积分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2178 先看到这篇博客:https://www.cnblogs.com/heisenberg- ...

  4. 上海-北京间通过Azure Storage的RA-GRS类型的存储账户进行快速复制

    Azure的Blob存储分成多种类型,目前主要有: 其中RA-GRS可以在上海-北京两个数据中心间同步数据.并且,在第二个数据中心可以只读的方式读取这个存储账户中的Blob内容. 虽然GRS采用的是准 ...

  5. Python之常用模块(二)

    shelve xml处理 configparser hashlib logging   shelve模块 shelve是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持 ...

  6. js遍历for,forEach, for in,for of

    ECMAScript5(es5)有三种for循环 简单for for in forEach ECMAScript6(es6)新增 for of 简单for for是循环的基础语法,也是最常用的循环结构 ...

  7. 解决启动SQL Server Management Studio 17时报Cannot find one of more components...的问题

    刚装好SSMS 17.1准备体验,弹出: 一番搜索,普遍办法都是安装VS2015独立shell.删除某个注册表项什么的,没用,首先这个shell我是装了的,然后也没有那个注册表项.我自己尝试过重装sh ...

  8. 没办法,SVD就讲的这么好

    2)奇异值: 下面谈谈奇异值分解.特征值分解是一个提取矩阵特征很不错的方法,但是它只是对方阵而言的,在现实的世界中,我们看到的大部分矩阵都不是方阵,比如说有N个学生,每个学生有M科成绩,这样形成的一个 ...

  9. SQL 时间及字符串操作

    都是一些很基础很常用的,在这里记录一下 获取年月日: year(时间) ---获取年,2014 month(时间) ----获取月,5 day(时间) -----获取天,6 如果月份或日期不足两位数, ...

  10. .Net下RabbitMQ发布订阅模式实践

    一.概念AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计.消息中间件主要用于组件之间的解耦,消息的发 ...