题意:就是求石子归并。

题解:当范围在100左右是可以之间简单的区间dp,如果范围在1000左右就要考虑用平行四边形优化。

就是多加一个p[i][j]表示在i到j内的取最优解的位置k,注意能使用平行四边形优化的条件:

1.证明w满足四边形不等式,这里w是m的附属量,形如m[i,j]=opt{m[i,k]+m[k,j]+w[i,j]},此时大多要先证明w满足条件才能进一步证明m满足条件

2.证明m满足四边形不等式

3.证明s[i,j-1]≤s[i,j]≤s[i+1,j]

。如果在10000左右时就要用GarsiaWachs算法

 

推荐一个博客http://www.cnblogs.com/jiu0821/p/4493497.html

有详细解释。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int inf = 0X3f3f3f3f;
long long dp[200][200] , a[200] , sum[200];
int main() {
int n;
scanf("%d" , &n);
for(int i = 1 ; i <= n ; i++) {
scanf("%lld" , &a[i]);
}
memset(dp , inf , sizeof(dp));
for(int i = 1 ; i <= n ; i++) {
dp[i][i] = 0;
}
sum[0] = 0;
for(int i = 1 ; i <= n ; i++) {
sum[i] = sum[i - 1] + a[i];
}
for(int l = 1 ; l < n ; l++) {
for(int i = 1 ; i <= n && i + l <= n ; i++) {
int j = l + i;
for(int k = i ; k < j ; k++) {
dp[i][j] = min(dp[i][k] + dp[k + 1][j] + sum[j] - sum[i - 1] , dp[i][j]);
}
}
}
printf("%lld\n" , dp[1][n]);
return 0;
}
////////////
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int inf = 0X3f3f3f3f;
long long dp[2010][2010] , a[2010] , sum[2010] ;
int p[2010][2010];
int main() {
int n;
scanf("%d" , &n);
for(int i = 1 ; i <= n ; i++) {
scanf("%lld" , &a[i]);
}
memset(dp , inf , sizeof(dp));
for(int i = 1 ; i <= 2 * n ; i++) {
dp[i][i] = 0;
p[i][i] = i;
}
sum[0] = 0;
for(int i = n + 1 ; i <= 2 * n ; i++) {
a[i] = a[i - n];
}
for(int i = 1 ; i <= 2 * n ; i++) {
sum[i] = sum[i - 1] + a[i];
}
for(int l = 1 ; l < n ; l++) {
for(int i = 1 ; i <= 2 * n && i + l <= 2 * n ; i++) {
int j = l + i;
for(int k = p[i][j - 1] ; k <= p[i + 1][j] ; k++) {
if(dp[i][j] > dp[i][k] + dp[k + 1][j] + sum[j] - sum[i - 1]) {
dp[i][j] = dp[i][k] + dp[k + 1][j] + sum[j] - sum[i - 1];
p[i][j] = k;
}
}
}
}
long long MIN = dp[1][n];
for(int i = 2 ; i <= n ; i++) {
MIN = min(MIN , dp[i][i + n - 1]);
}
printf("%lld\n" , MIN);
return 0;
}
////////////////
#include <iostream>
#include <cstring>
using namespace std;
#define LL long long
const int MAXN = 50005;
int n, num;
LL ans;
int dp[MAXN];
void combine(int now) {
int j;
int temp = dp[now - 1] + dp[now];
ans += (LL)temp;
for(int i = now; i < num - 1; i++) dp[i] = dp[i + 1];
num--;
for(j = now - 1; j > 0 && dp[j - 1] < temp; j--) dp[j] = dp[j - 1];
dp[j] = temp;
while(j >= 2 && dp[j - 2] <= dp[j]) {
int d = num - j;
combine(j - 1);
j = num - d;
}
}
int main()
{
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d", &dp[i]);
num = 1, ans = 0;
for(int i = 1; i < n; i++)
{
dp[num++] = dp[i];
while(num>=3 && dp[num-3]<=dp[num-1]) combine(num - 2);
}
while(num > 1) combine(num - 1);
printf("%lld\n", ans);
return 0;
}

51 nod 石子归并 + v2 + v3(区间dp,区间dp+平行四边形优化,GarsiaWachs算法)的更多相关文章

  1. 51nod 1022 石子归并 V2 —— DP四边形不等式优化

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1022 1022 石子归并 V2  基准时间限制:1 秒 空间限 ...

  2. [51nod 1022] 石子归并v2 [dp+四边形不等式优化]

    题面: 传送门 思路: 加强版的石子归并,现在朴素的区间dp无法解决问题了 首先我们破环成链,复制一条一样的链并粘贴到原来的链后面,变成一个2n长度的序列,在它上面dp,效率O(8n^3) 显然是过不 ...

  3. 51nod1022 石子归并 V2

    证明w满足四边形不等式,这里w是m的附属量,形如m[i,j]=opt{m[i,k]+m[k,j]+w[i,j]},此时大多要先证明w满足条件才能进一步证明m满足条件证明m满足四边形不等式证明s[i,j ...

  4. 石子合并(直线版+环形版)&(朴素写法+四边形优化+GarsiaWachs算法)

    石子合并-直线版 (点击此处查看题目) 朴素写法 最简单常见的写法就是通过枚举分割点,求出每个区间合并的最小花费,从而得到整个区间的最小花费,时间复杂度为O(n^3),核心代码如下: ; i < ...

  5. 51Nod 1022 石子归并 V2(区间DP+四边形优化)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1022 题目大意: N堆石子摆成一个环.现要将石子有次序地合并成 ...

  6. 51 Nod 1068 Bash游戏v3

    1068 Bash游戏 V3  题目来源: Ural 1180 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 有一堆石子共有N个.A B两个人轮流 ...

  7. 51 Nod Bash 游戏v2

    1067 Bash游戏 V2  基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  取消关注 有一堆石子共有N个.A B两个人轮流拿,A先拿.每次只能拿1,3 ...

  8. 51 Nod 1500 苹果曼和树(树形dp)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1500 思路: 树形dp. 我们考虑当前结点 i ,对于结点 i ,它可以 ...

  9. 51 Nod 1006 最长公共子序列(LCS & DP)

    原题链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1006 题目分析: 首先先知道LCS问题,这有两种: Long ...

随机推荐

  1. Asp.Net MVC HttpPost用法

    一个Action只能用一个http 特性,例如:HttpPost 不能与HttpGet 或者多个HttpPost重复使用,否则会出错 也可以用 [AcceptVerbs("put" ...

  2. Java模拟并解决缓存穿透

    什么叫做缓存穿透 缓存穿透只会发生在高并发的时候,就是当有10000个并发进行查询数据的时候,我们一般都会先去redis里面查询进行数据,但是如果redis里面没有这个数据的时候,那么这10000个并 ...

  3. 第十五章 LVM管理和ssm存储管理器使用 随堂笔记

    第十五章 LVM管理和ssm存储管理器使用 本节所讲内容: 15.1 LVM的工作原理 15.2 创建LVM的基本步骤 15.3 实战-使用SSM工具为公司的邮件服务器创建可动态扩容的存储池 LVM的 ...

  4. Thread、ThreadPool、Task、Parallel、Async和Await基本用法、区别以及弊端

    多线程的操作在程序中也是比较常见的,比如开启一个线程执行一些比较耗时的操作(IO操作),而主线程继续执行当前操作,不会造成主线程阻塞.线程又分为前台线程和后台线程,区别是:整个程序必须要运行完前台线程 ...

  5. C++学习想法

    今天是周一,今天做早操的时候舍友说准备买一本C++基础的书.我觉得这样的想法很好,突然想到自己最近几天因为自己私人原因事情很忙,蛋这不能成为我不学C++的理由.所以我在这规划了我这一周的学习进程.首先 ...

  6. Simple Windows Service in C++

    本文是来自CodeProject中的一篇名为Simple Windows Service in C++的译文,原文地址为:https://www.codeproject.com/Articles/49 ...

  7. 7.17 正则表达式 re模块

    在介绍正则表达式和re模块之前,先简要介绍一下 正则表达式与re模块的关系 1.正则表达式是一门独立的技术,任何语言均可使用 2.python中要想使用正则表达式需要通过re模块 正则表达式 元字符 ...

  8. #348 大陆争霸(DIjkstra)

    在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的 克里斯国.两个国家的人民分别信仰两个对立的神:杰森国信仰象征黑暗和毁灭 的神曾·布拉泽,而克里斯国信仰象征光明和永恒的神斯普林·布拉 ...

  9. GOF23-工厂模式

    1.什么是工厂模式 就是实现创建者与调用者分离,工厂模式的核心(灵魂)其实就是:分工.   2.工厂模式有哪些 简单工场模式(静态工厂) 简单工厂模式也叫静态工厂模式,就是工厂类一般使用静态方法,通过 ...

  10. 康托(Cantor)展开

    直接进入正题. 康托展开 Description 现在有"ABCDEFGHIJ”10个字符,将其所有的排列中按字典序排列,给出任意一种排列,说出这个排列在所有的排列中是第几小的? Input ...