【整理】石子合并问题(四边形不等式DP优化)
有很多种算法:
1,任意两堆可以合并:贪心+单调队列。
2,相邻两堆可合并:区间DP (O(n^3)) )。
3,相邻,四边形不等式优化DP (O(n^2) )。
4,相邻,GarsiaWachs算法 (O(nlgn))。
这里实现了第2,3种解法:(个人的区间DP习惯从后面向前面扫)
看起来第四种还是比较重要的,有空再搞。
2:暴力DP
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream> using namespace std;
const int inf=;
int a[],dp[][],sum[];
int main()
{
int n,i,j,k;
scanf("%d",&n);
for(i=;i<=n;i++) scanf("%d",&a[i]);
for(i=;i<=n;i++) sum[i]=sum[i-]+a[i];
for(i=;i<=n;i++)
for(j=;j<=n;j++) dp[i][j]=inf;
for(i=;i<=n;i++) dp[i][i]=; for(i=n-;i>=;i--)
for(j=i+;j<=n;j++)
for(k=i;k<=j;k++)
dp[i][j]=min(dp[i][k]+dp[k+][j]+sum[j]-sum[i-],dp[i][j]);
printf("%d\n",dp[][n]);
return ;
}
3:优化DP
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#define LL long long
using namespace std;
LL min(LL a,LL b){
if(a<b) return a;return b;
}
const LL inf=;
LL a[],dp[][],sum[];
LL s[][],ans=inf;
int main()
{
LL n,i,j,k;
scanf("%lld",&n);
for(i=;i<=n;i++) {
scanf("%lld",&a[i]);
a[i+n]=a[i];
}
for(i=;i<=*n;i++) sum[i]=sum[i-]+a[i];
for(i=;i<=*n;i++)
for(j=;j<=*n;j++)
dp[i][j]=(i==j?:inf); for(i=*n-;i>=;i--)
for(j=i+;j<=*n;j++){
LL L=s[i][j-]?s[i][j-]:i;
LL R=s[i+][j]?s[i+][j]:n+n;
for(k=L;k<=R;k++){
LL tmp=dp[i][k]+dp[k+][j]+sum[j]-sum[i-];
if(dp[i][j]>tmp){
dp[i][j]=tmp;
s[i][j]=k;
}
}
}
for(i=;i<=n;i++)
ans=min(ans,dp[i][i+n-]);
printf("%lld\n",ans);
return ;
}
【整理】石子合并问题(四边形不等式DP优化)的更多相关文章
- 区间DP石子合并问题 & 四边形不等式优化
入门区间DP,第一个问题就是线性的规模小的石子合并问题 dp数组的含义是第i堆到第j堆进行合并的最优值 就是说dp[i][j]可以由dp[i][k]和dp[k+1][j]转移过来 状态转移方程 dp[ ...
- 石子合并(四边形不等式优化dp) POJ1160
该来的总是要来的———————— 经典问题,石子合并. 对于 f[i][j]= min{f[i][k]+f[k+1][j]+w[i][j]} From 黑书 凸四边形不等式:w[a][c]+w[b][ ...
- [HDU3516] Tree Construction [四边形不等式dp]
题面: 传送门 思路: 这道题有个结论: 把两棵树$\left[i,k\right]$以及$\left[k+1,j\right]$连接起来的最小花费是$x\left[k+1\right]-x\left ...
- [HDU3480] Division [四边形不等式dp]
题面: 传送门 思路: 因为集合可以无序选择,所以我们先把输入数据排个序 然后发先可以动归一波 设$dp\left[i\right]\left[j\right]$表示前j个数中分了i个集合,$w\le ...
- [POJ1160] Post Office [四边形不等式dp]
题面: 传送门 思路: dp方程实际上很好想 设$dp\left[i\right]\left[j\right]$表示前$j$个镇子设立$i$个邮局的最小花费 然后状态转移: $dp\left[i\ri ...
- 记忆的轮廓 期望 四边形不等式dp|题解
记忆的轮廓 题目描述 通往贤者之塔的路上,有许多的危机.我们可以把这个地形看做是一颗树,根节点编号为1,目标节点编号为n,其中1-n的简单路径上,编号依次递增,在[1,n]中,一共有n个节点.我们把编 ...
- 51Nod 1021 石子合并 Label:Water DP
N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价.计算将N堆石子合并成一堆的最小代价. 例如: 1 2 3 4,有 ...
- NYOJ737石子合并(二)-(区间dp)
题目描述: 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆.求出 ...
- P1880 [NOI1995]石子合并-(环形区间dp)
https://www.luogu.org/problemnew/show/P1880 解题过程:本次的题目把石子围成一个环,与排成一列的版本有些不一样,可以在后面数组后面再接上n个元素,表示连续n个 ...
随机推荐
- SqlHelper简单实现(通过Expression和反射)1.引言
之前老大说要改变代码中充斥着各种Select的Sql语句字符串的情况,让我尝试着做一个简单的SqlHelper,要具有以下功能: 1.不要在业务代码中暴露DataTable或者DataSet类型: 2 ...
- mfc学习---文档视图架构
MFC的AppWizard可以生成三种类型的应用程序:基于对话框的应用.单文档应用(SDI)和多文档应用(MDI). 一般情况下,采用文档/视结构的应用程序至少应由以下对象组成: 1. ...
- winform webbrowser禁用网页target=blank
/// <summary> /// 屏蔽target=_blank 的弹出窗口 /// </summary> /// <param name="sender&q ...
- NEVER QUIT. NEVER SAY NEVER.
有志者不是从不失败,而是从不妥协. NEVER QUIT. NEVER SAY NEVER. 2015/09/15 Winners are not those who never fail but t ...
- CentOS 7如何将.deb文件转换.rpm
1.首先下载alien工具 http://ftp.de.debian.org/debian/pool/main/a/alien/ http://ftp.de.debian.org/debian/po ...
- 解决You have new mail in /var/spool/mail/root提示
终端远程登陆后经常提示You have new mail in /var/spool/mail/root 这个提示是LINUX会定时查看LINUX各种状态做汇总,每经过一段时间会把汇总的信息发送的ro ...
- linux 终端分屏命令
比如:某文件夹下有文件:vector.cc, substr.cc 1.使用vim命令打开任意一个文件:vim vector.cc打开第一个文件.如下图所示: 2.按:"Esc"键 ...
- Android -- junit测试框架,logcat获取log信息
1. 相关概念 白盒测试: 知道程序源代码. 根据测试的粒度分为不同的类型 方法测试 function test 单元测试 unit test 集成 ...
- TED字幕摘抄
1.丹·吉尔伯特: 我们为什么快乐?http://v.163.com/movie/2012/12/0/S/M8HHB6LDT_M8HHCBM0S.html 在两百万年中, 大脑脑容量从我们祖先能人的1 ...
- Memcached add 命令
Memcached add 命令用于将 value(数据值) 存储在指定的 key(键) 中. 如果 add 的 key 已经存在,则不会更新数据,之前的值将仍然保持相同,并且您将获得响应 NOT_S ...