DP优化--四边形不等式

四边形不等式

使用范围:区间序列DP求最小值(一定是最小值)
对于动态规划转移方程

dp[i][j]=min(dp[i][k],dp[k+1][j])+w(i,j);

其中w(i,j)只受i,j取值影响
如果满足下面两个条件
1.区间单调性:如果对于ii<jj,w(i,j)w(i,j)(即小区间取值大区间取值)
2.四边形不等式:ii<jj,w(i,j)+w(i,j)w(i,j)+w(i,j)

即中的红线总长 蓝线总长

如果w(i,j)同时满足区间单调性和四边形不等式

那么f(i,j)满足四边形不等式

S(i,j)F(i,j)在取到最优解时的决策点k

那么决策本身具有单调性,即满足S(i,j)S(i,j+1)S(i+1,j+1)

j代替j+1得到

S(i,j1)S(i,j)S(i,j+1)

转移方程变为

F(i,j)=min(F(i,k)+F(k+1,j))+w(i,j); (S(i,j1)kS(i+1,j))

可以证明,他将时间复杂度降到了O(n2)

什么时候使用四边形不等式?

只需要牢记公式

S(i,j1)S(i,j)S(i,j+1)

考试时可以打一张决策表看是否满足上面式子,满足可以使用四边形不等式

1.序列DP有时可以使用四边形不等式优化,但仅仅是常数优化

2.需要注意四边形不等式仅针对求最小值的情况

3.注意S数组(下标取值范围)需要初始化,S[i][i]=i

例题

P1880石子合并
这道题的四边形不等式非常裸,但要注意求最大值不能用四边形不等式,注意到最大值可以使用决策单调性优化

求最大值时f[i][j]一定是从f[i][j1]f[i+1][j]转移过来的,所以可以将第三维优化掉

Code

#include<iostream>
#include<cstdio>
#define maxn 2005
#define INF 0x3f3f3f3f
#define re register
using namespace std;
int a[maxn],sum[maxn];
int f1[maxn][maxn],f2[maxn][maxn];
int s[maxn][maxn];
int n,tmp,pos,tmp2;
int ans1=0x3f3f3f3f,ans2;
int main()
{
	scanf("%d",&n);
	for(re int i=1;i<=n;++i)
	{
		scanf("%d",&a[i]);
		a[i+n]=a[i];
	}
	for(re int i=1;i<=2*n;++i)
	{
		sum[i]=sum[i-1]+a[i];
		s[i][i]=i;//决策区间初始化 
		//这里的f[i][i]都是0不用初始化因为求max就是初始化为0
		//求min使用决策单调性不需要初始化了 
	}
	for(re int i=2*n-1;i>=1;--i)
	 for(re int j=i+1;j<=2*n;++j)
	 {
	 	f2[i][j]=max(f2[i][j-1],f2[i+1][j])+sum[j]-sum[i-1];
	 	 /*注意这句,
              求最大值不能用四边形不等式,
              因为最大值不满足单调性,
              但最大值有一个性质,
              即总是在两个端点的最大者中取到。
         */
         tmp=INF,pos=0;
         for(re int k=s[i][j-1];k<=s[i+1][j];++k)
         {
         	tmp2=f1[i][k]+f1[k+1][j]+(sum[j]-sum[i-1]);
         	if(tmp2<tmp) tmp=tmp2,pos=k;
         	f1[i][j]=tmp;
         	s[i][j]=pos;
		 }
	 }
	for(re int i=1;i<=n;++i)
	{
		ans1=min(ans1,f1[i][i+n-1]);
		ans2=max(ans2,f2[i][i+n-1]);
	}
	printf("%d\n%d",ans1,ans2);
	return 0;
}
posted @   __Liuz  阅读(230)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示