题目链接:http://www.hihocoder.com/problemset/problem/1636

题目描述

在中国古代神话中,盘古是时间第一个人并且开天辟地,它从混沌中醒来并把混沌分为天地。

刚开始地上是没有山的,只有满地的石头。

这里有 \(N\) 堆石头,标号为从 \(1\) 到 \(N\) 。盘古想要把它们合成一堆建造一座大山。如果某些堆石头的数量总和是 \(S\) ,盘古需要 \(S\) 秒才能把它们合成一堆,这新的一堆石头的数量就是 \(S\) 。

不幸的是,每一次盘古只能把连续的 \(L\) 到 \(R\) 堆石头合并成一堆。

盘古希望尽快把所有石头合成一堆。

你能帮帮他吗?如果没有解,则输出 \(0\) 。

解题思路

可以把合并所有石头的过程拆分成几个子步骤,首先合并连续的一些,然后再合并连续的一些,大区间的结果可以由小区间推出,所以就从小区间开始考虑,逐步推向大区间,可以用 dp[i][j][k] 表示区间 [i,j] 分成 k 堆得最小代价,对于固定的一个区间,肯定是取所有情况的最小值,最后答案是 dp[1][n][1] ,注意边界处理,包括刚开始的初始化。

然后就是代码处理中的一些细节了。

首先将所有的 f[i][j][k] 置为 INF

然后对于所有的初始状态(即 f[i][j][j-i+1] )都置为 \(0\) 。

因为区间 \([i,j]\) 内本身就有 \(j-i+1\) 个元素,所以这些元素本身就这么多堆,是不需要花费代价去划分的。这就是我所说的初始状态。

然后就是合并区间了,区间合并一般都是小区间开始合并到大区间,我们这里也不例外(记忆化搜索的话就得反着来了)。

对于一个区间 \([l,r]\) ,它要么是直接合并成一对,要么是若干个区间拼接到一起。所以我们这里分情况讨论:

直接合并

如果区间 \([l,r]\) 直接合并,那么合并成一对的最小代价应该是 \(f[l][r][1]\) 。

那么对于区间 \([l,r]\) ,我一定可以将其查分成两个区间 \([l,i]\) 和 \([i+1,r]\) ,其中坐区间有 \(j\) 个元素,右区间有 \(1\) 个元素,并且满足 \(L \le j+1 \le R\) 。

于是我们可以从 \(l \sim r-1\) 枚举 \(i\) ,从 \(L-1 \sim R-1\) 枚举 \(j\) ,

则 \(f[l][r][1] = \min(f[l][i][j]+f[i+1][r][1]) + sum[r] - sum[l-1]\) 。(这里 \(sum[r] - sum[l-1]\) 表示区间 \([l,r]\) 范围内的石子数量之和)

区间拼接

这里讲的区间拼接其实就是对于两个区间 \([l,j]\) 和 \([j+1,r]\) ,假设他们分别有 \(i-1\) 堆和 \(1\) 堆石子,那么这个区间总共有 \(i\) 堆石子。

区间拼接就不需要考虑合并了。

所以对于区间 \([l,r]\) 包含 \(i\) 堆石子的情况,它对应状态 \(f[l][r][i]\) ,那么它总能拆分成两个状态(\(f[l][j][i-1]\) 和 \(f[j+1][r][1]\) ,其中 \(l \le j \lt r\))的拼接。

可以推导出状态转移方程为: \(f[l][r][i] = min(f[l][j][i-1] + f[j+1][r][1])\) ,其中 \(2 \le i \le len,l \le j \lt r\) 。

实现代码如下:

#include <bits/stdc++.h>
using namespace std;
#define INF (1<<29)
const int maxn = 110;
int n, L, R, a[maxn], sum[maxn], f[maxn][maxn][maxn];
int main() {
while (~scanf("%d%d%d", &n, &L, &R)) {
for (int i = 1; i <= n; i ++) scanf("%d", a+i);
for (int i = 1; i <= n; i ++) sum[i] = sum[i-1] + a[i];
for (int i = 1; i <= n; i ++) for (int j = 1; j <= n; j ++) for (int k = 1; k <= n; k ++) f[i][j][k] = INF;
for (int l = 1; l <= n; l ++) for (int r = l; r <= n; r ++) f[l][r][r-l+1] = 0;
for (int len = 1; len <= n; len ++) {
for (int l = 1; l+len-1 <= n; l ++) {
int r = l+len-1;
for (int i = l; i < r; i ++) {
for (int j = L-1; j < R; j ++) {
f[l][r][1] = min(f[l][r][1], f[l][i][j] + f[i+1][r][1] + sum[r] - sum[l-1]);
}
}
for (int i = 2; i < len; i ++) {
for (int j = l; j < r; j ++) {
f[l][r][i] = min(f[l][r][i], f[l][j][i-1] + f[j+1][r][1]);
}
}
}
}
if (f[1][n][1] == INF) puts("0");
else printf("%d\n", f[1][n][1]);
}
return 0;
}

2017 ACM-ICPC亚洲区域赛北京站J题 Pangu and Stones 题解 区间DP的更多相关文章

  1. 【2017 ICPC亚洲区域赛北京站 J】Pangu and Stones(区间dp)

    In Chinese mythology, Pangu is the first living being and the creator of the sky and the earth. He w ...

  2. 2015 ACM / ICPC 亚洲区域赛总结(长春站&北京站)

    队名:Unlimited Code Works(无尽编码)  队员:Wu.Wang.Zhou 先说一下队伍:Wu是大三学长:Wang高中noip省一:我最渣,去年来大学开始学的a+b,参加今年区域赛之 ...

  3. 【2016 ICPC亚洲区域赛北京站 E】What a Ridiculous Election(BFS预处理)

    Description In country Light Tower, a presidential election is going on. There are two candidates,   ...

  4. Digit sum (第 44 届 ACM/ICPC 亚洲区域赛(上海)网络赛)进制预处理水题

    131072K   A digit sum S_b(n)Sb​(n) is a sum of the base-bb digits of nn. Such as S_{10}(233) = 2 + 3 ...

  5. Known Notation括号匹配类问题(2014年ACM/ICPC 亚洲区域赛牡丹江)

    题意: 给你数字或 * 的串,你可以交换一个*和数字.在最前面添1.在一个地方插入*,问你使串满足入栈出栈的(RNP)运算法则. 思路: 引用:https://blog.csdn.net/u01158 ...

  6. 2014ACM/ICPC亚洲区域赛牡丹江站汇总

    球队内线我也总水平,这所学校得到了前所未有的8地方,因为只有两个少年队.因此,我们13并且可以被分配到的地方,因为13和非常大的数目.据领队谁oj在之上a谁去让更多的冠军.我和tyh,sxk,doub ...

  7. icpc 2017北京 J题 Pangu and Stones 区间DP

    #1636 : Pangu and Stones 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 In Chinese mythology, Pangu is the fi ...

  8. 【2017 ICPC亚洲区域赛沈阳站 K】Rabbits(思维)

    Problem Description Here N (N ≥ 3) rabbits are playing by the river. They are playing on a number li ...

  9. HDU - 6215 2017 ACM/ICPC Asia Regional Qingdao Online J - Brute Force Sorting

    Brute Force Sorting Time Limit: 1 Sec  Memory Limit: 128 MB 题目连接 http://acm.hdu.edu.cn/showproblem.p ...

随机推荐

  1. python selenium 测试浏览器(IE,FF,Chrome)

    browser_engine.py # coding=utf-8 from selenium import webdriver class BrowserEngine(object): "& ...

  2. Tyvj-1338 QQ农场

    P1338 QQ农场 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 Sandytea前段时间沉迷于QQ农场中……一天夜里,他梦见来到好友X的农场上…… 描述 ...

  3. PHP 试题(1)

    1.__FILE__表示什么意思?(5分)文件的完整路径和文件名.如果用在包含文件中,则返回包含文件名.自 PHP 4.0.2 起,__FILE__ 总是包含一个绝对路径,而在此之前的版本有时会包含一 ...

  4. [C#] 调试silverlight的时候,总是报“向占位程序传送了空的索引指针”

    这是由于visual studio在调试silverlight的时候,必须和ie一起工作. 按照以下步骤可以把ie设为visual studio的默认浏览器(不用修改操作系统的默认浏览器): 1) 在 ...

  5. Python--day71--ORM分组补充

    1,ORM映射对应的sql语句: 2,QuerySet QuerySet方法大全 ########################################################### ...

  6. nginx 301 将不带www域名,重定向到www域名

    // nginx 官方推荐 server { listen 80; server_name example.org; return 301 http://www.example.org$request ...

  7. Python--day65--模板语言之tags

    Tags for循环 普通for循环 <ul> {% for user in user_list %} <li>{{ user.name }}</li> {% en ...

  8. js(四) 全选/全不选和反选

    思路:通过选择全选的选框的状态stuts 即true/false控制其他选框. 首先 我们要通过.checked方法获取选框(全选/全不选)的值. function all(){ var stuts= ...

  9. phpstorm 有的单词下有下划线,怎么去掉?

    settings -> Editor -> Colors & Fonts -> General ->Errors and Warnings然后你会看见下面的示例代码.点 ...

  10. vue用法父组件调用子组件方法--->$refs

    vue下载excel模板(放入弹框独立出来)后再导入表格 子组件 <el-dialog title="导入" :visible.sync="dialogVisibl ...