题目:

有N堆石子,现要将石子有序的合并成一堆,规定如下:

1.每次只能移动相邻的2堆石子合并 
2.合并花费为新合成的一堆石子的数量。

求将这N堆石子合并成一堆的总花费最小(或最大)。

样例:

输入:7

13 7 8 16 21 4 18

输出:239

说是简单dp,刚开始学dp还是有点困难,这个题目我花了很长时间了。今天差不多才理清里面的大部分细节。

首先,合并相邻的石子,合并时,可以两堆,三堆,四堆。两堆的时候就只能合并相邻两堆;三堆的时候就有多种选择了,1+2 和 2+1;四堆的时候,1+3 和 2+2 和 3+1;

2堆的时候:

3堆的时候:

4堆也是类似。

现在我们拿样例来分析一下。

1.首先是状态转移方程。

设f[i][j]是从第i堆到第j堆的最优值。  配和上面的图,两堆的时候:f[1][2] f[2][3] f[3][4] f[4][5] f[5][6] f[6][7]; 三堆的时候:f[1][3] f[2][4] ......。

然后 f[1][3] = f[1][1] + f[2][3] + s[3] - s[0];    f[1][3] = f[1][2] + f[3][3] + s[3] - s[0];  有这两种情况。取他们的最小值。

转移方程就是 f[i][j] = min( f[i][j], f[i][k] + f[k+1][j] +s[j]-s[i]);

2.为什么是s[3] - s[0]呢?

s[3] - s[0]是从第1堆到第3堆的总和。但是花销并不仅仅是总和, 合并3堆的时候,其实是需要合并两次,所以每堆都用到了两次,而自己和自己合并,花费的价值为0。f[1][3] = f[1][1] + f[2][3] + s[3] - s[0]; f[1][1] + f[2][3]这个是一次合并,s[3] - s[0]这个是另外一次合并。

3.输出的答案是f[1][n]。

代表从第1堆到第n堆的最小花费。

4.为什么要倒推?

因为顺推的时候,f[1][3] = f[2][3] + f[1][1] ,顺推的话,i从1开始,那f[2][3]这个时候是没办法知道的。所以倒推。

代码:

#include<bits/stdc++.h>
using namespace std;
const int M = 10009; int f[M][M]; // f[i][j] 代表第 i 堆石子 到 第 j 堆石子的最优值
int x,s[M]; int main(){
int n;
cin>>n;
memset(f,1011/3,sizeof(f));
for(int i = 1; i <= n; i++)
{
cin>>x;
s[i] = s[i-1] + x; //s[i] 代表前 i 堆石子的总和
} for(int i = 1; i <= n; i++) f[i][i] = 0; for(int i = n-1; i >= 1; i--)
for(int j = i+1; j <= n; j++)
for(int k = i; k <= j-1; k++)
{
f[i][j] = min(f[i][j],f[i][k]+f[k+1][j]+s[j]-s[i-1]);
} cout<<f[1][n]; return 0;
}

dp入门 石子相邻合并 详细带图讲解的更多相关文章

  1. DP之石子堆合并问题

    相邻 环形 总结 (1)相邻:在一个圆形操场的四周摆放着n堆石子(n<= 100),现要将石子有次序地合并成一堆.规定每次只能选取相邻的两堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得 ...

  2. HRBUST - 1818 石子合并 区间dp入门

    有点理解了进阶指南上说的”阶段,状态和决策“ /* 区间dp的基础题: 以区间长度[2,n]为阶段,枚举该长度的区间,状态dp[l][r]表示合并区间[l,r]的最小费用 状态转移方程dp[l][r] ...

  3. IT技术学习指导之Linux系统入门的4个阶段(纯干货带图)

    IT技术学习指导之Linux系统入门的4个阶段(纯干货带图) 全世界60%的人都在使用Linux.几乎没有人没有受到Linux系统的"恩惠",我们享受的大量服务(包括网页服务.聊天 ...

  4. wyh的dp入门刷题笔记

    0: 靠前感觉之前dp抄题解都是抄的题解,自己从没有真正理解过dp.wyh下了很大决心从头学dp,于是便有了这篇文章. 1.背包 前四讲01背包&多重背包&完全背包(混合背包) :樱花 ...

  5. 能量项链(区间DP入门)

    题面:能量项链https://www.luogu.com.cn/problem/P1063 乍一看和石子合并差不多,可是多了头值和尾值,看起来十分麻烦 我们画一张图,紫色表示头值,蓝色表示尾值.规定西 ...

  6. poj 3254 状压dp入门题

    1.poj 3254  Corn Fields    状态压缩dp入门题 2.总结:二进制实在巧妙,以前从来没想过可以这样用. 题意:n行m列,1表示肥沃,0表示贫瘠,把牛放在肥沃处,要求所有牛不能相 ...

  7. 数位dp入门 hdu2089 不要62

    数位dp入门 hdu2089 不要62 题意: 给定一个区间[n,m] (0< n ≤ m<1000000),找出不含4和'62'的数的个数 (ps:开始以为直接暴力可以..貌似可以,但是 ...

  8. poj3254状压DP入门

    G - 状压dp Crawling in process... Crawling failed Time Limit:2000MS     Memory Limit:65536KB     64bit ...

  9. Spark+ECLIPSE+JAVA+MAVEN windows开发环境搭建及入门实例【附详细代码】

    http://blog.csdn.net/xiefu5hh/article/details/51707529 Spark+ECLIPSE+JAVA+MAVEN windows开发环境搭建及入门实例[附 ...

随机推荐

  1. mysql与redis在各种情况下性能对比

    数据表结构 CREATE TABLE `jx_goods_test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `goods_name` varchar(100) ...

  2. LeetCode 821 Shortest Distance to a Character 解题报告

    题目要求 Given a string S and a character C, return an array of integers representing the shortest dista ...

  3. 洛谷P3121 审查(黄金)Censoring(Gold) [USACO15FEB] AC自动机

    正解:AC自动机 解题报告: 传送门! 啊我好呆啊其实就挺模板题的,,,只是要一个栈搞一下,,,然后我就不会了,,,是看了题解才get的,,,QAQ 然后写下解法趴QwQ 首先看到多串匹配不难想到AC ...

  4. 7-通用GPIO

    7-通用GPIO 1.I/O 端口控制寄存器 每个 GPIO 有 4 个 32 位存储器映射的控制寄存器(GPIOx_MODER.GPIOx_OTYPER.GPIOx_OSPEEDR.GPIOx_PU ...

  5. 解决因为Telnet没有启动导致FTP无法连接的问题

    今天ytkah在其他电脑上想用ftp传点东西发现居然连接不上,查看了一下服务器安全组规则里的端口,也没有相关屏蔽.问了一下运维,他说可能是Telnet没有开启.就试着去看看有没问题.打开 控制面板 - ...

  6. android下的样式

    android中控件,假如我们把样式都写死在控件的配置文件上的话.一旦改动可谓牵一发而动千军.那么我们能够把样式写在style.xml文件里.然后引用,在API14以上版本号. 该文件位于values ...

  7. 运维自动化ansible基础

    云计算三种服务架构 IAAS: 不提供OS  只购买硬件(网络,存储,计算) PAAS: 提供硬件和OS和开发和运行环境  只需要开发应用软件 SAAS: 提供 硬件 os 软件   相当于直接购买软 ...

  8. sap 申请 新系统用户

    1:打开sap  logon, 进入到以下界面,connection上面 ,右键>add new entry 2: 搜索自己需要的系统名称. 3:一直next,直到完成 4: 双击该系统,进入以 ...

  9. 118A

    #include <iostream> #include <cctype> #include <string> using namespace std; int m ...

  10. CentOS里alias命令

    alias命令 功能描述:我们在进行系统的管理工作一定会有一些我们经常固定使用,但又很长的命令.那我们可以给这些这一长串的命令起一个别名.之后还需要这一长串命令时就可以直接以别名来替代了.系统中已经有 ...