【模板】斜率优化

斜率优化问题:

一些形如$dp(i)=min\{dp(i),dp(j)+f(i)*(\cdots)\}$的转移方程无法用单调队列优化。然而时间复杂度又不能$O(n^2)$。

这种情况下对于$dp(i)$,假如从$j$转移比从$k$转移更优,$j,k$需要满足一些条件。

我们通过整理这些条件可以将每个$i$抽象成坐标系中的一个点并用单调队列维护上凸/下凸包解决问题。

 

思路:

我们以HDU3507为例:

容易得出转移方程:$dp(i)=min\{dp(i),dp(j)+[sum(i)-sum(j)]^{2}+M\}$,其中$sum(i)=\sum_{k=1}^{i}C_k$。

然后发现好像不太会优化……不如打个暴力走人

对于某个i,假设从j转移比从k转移更优,则我们有:

$dp(j)+[sum(i)-sum(j)]^{2}+M<dp(k)+[sum(i)-sum(k)]^{2}+M$

经过一些代数变换,我们得到:

$2\times sum(i)\times[sum(k)-sum(j)]<dp(k)+sum(k)^{2}-[dp(j)+sum(j)^2]$

我们设j位于k前面,那么$sum(k)-sum(j)>0$,移项得到:

$2\times sum(i)<\frac{dp(k)+sum(k)^{2}-[dp(j)+sum(j)^2]}{sum(k)-sum(j)}$

发现右边就是过点$A(sum(k),dp(k)+sum(k)^{2})$和点$B(sum(j),dp(j)+sum(j)^{2})$的直线$AB$的斜率。

那么可以将每个$dp(i)$都按上面的方式转化成一个点放入坐标系中。

画图可以发现如果存在三个点形成上凸,那么中间那个点一定不是最优。

于是我们维护一些相邻两个点连线的斜率递增的点(下凸包)作为答案序列,

每次找到第一个与它右边的点连线的斜率$>2\times sum(i)$的点,它就是当前转移的最优值。

由于$2\times sum(i)$单调递增,我们可以用单调队列维护之,即每次删除答案点左边的所有点。

每个点只会入队出队一次,所以复杂度是线性的。

 

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>

using namespace std;
#define MAXN 1000005
#define MAXM 500005
#define INF 0x7fffffff
#define ll long long

inline ll read(){
    ll x=0,f=1;
    char c=getchar();
    for(;!isdigit(c);c=getchar())
        if(c=='-')
            f=-1;
    for(;isdigit(c);c=getchar())
        x=x*10+c-'0';
    return x*f;
}

ll N,M,C[MAXN],S[MAXN],q[MAXN],dp[MAXN];

inline ll getk(ll x1,ll x2) {return (dp[x2]+S[x2]*S[x2])-(dp[x1]+S[x1]*S[x1]);}

int main(){
    while(scanf("%d%d",&N,&M)!=EOF){
        for(ll i=1;i<=N;i++)
            C[i]=read(),S[i]=S[i-1]+C[i];
        ll head=1,tail=1; q[head]=0;
        for(ll i=1;i<=N;i++){
            while(head<tail && getk(q[head],q[head+1])<=2*S[i]*(S[q[head+1]]-S[q[head]])) head++;
            dp[i]=dp[q[head]]+(S[i]-S[q[head]])*(S[i]-S[q[head]])+M;
            while(head<tail && getk(q[tail-1],q[tail])*(S[i]-S[q[tail]])>=getk(q[tail],i)*(S[q[tail]]-S[q[tail-1]])) tail--;
            q[++tail]=i;
        }
        printf("%lld\n",dp[N]);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/YSFAC/p/10467264.html

管理后台HTML页面是Web开发中一种常见的实践,主要用于构建企业或组织内部的管理界面,具备数据监控、用户管理、内容编辑等功能。本文将探讨一套美观易用的二级菜单目录设计,帮助开发者创建高效且直观的后台管理系统。 HTML5:作为超文本标记语言的最新版本,HTML5增强了网页的互动性和可访问性,提供了更多语义元素,如<header>、<nav>、<section>、<article>等,有助于清晰地定义网页结构。在管理后台中,HTML5可用于构建页面布局,划分功能区域,并集成多媒体内容,如图像、音频和视频。 界面设计:良好的管理后台界面应具备清晰的导航、一致的布局和易于理解的图标。二级菜单目录设计能够有效组织信息,主菜单涵盖大类功能,次级菜单则提供更具体的操作选项,通过展开和折叠实现层次感,降低用户认知负担。 CSS:CSS是用于控制网页外观和布局的语言,可对HTML元素进行样式设置,包括颜色、字体、布局等。在管理后台中,CSS能够实现响应式设计,使页面在不同设备上具有良好的显示效果。借助CSS预处理器(如Sass或Less),可以编写更高效、模块化的样式代码,便于维护。 文件结构: guanli.html:可能是管理页面的主入口,包含后台的主要功能和布局。 xitong.html:可能是系统设置或配置页面,用于管理员调整系统参数。 denglu.html:登录页面,通常包含用户名和密码输入框、登录按钮,以及注册或忘记密码的链接。 image文件夹:存放页面使用的图片资源,如图标、背景图等。 css文件夹:包含后台系统的样式文件,如全局样式表style.css或按模块划分的样式文件。 响应式设计:在移动设备普及的背景下,管理后台需要支持多种屏幕尺寸。通过媒体查询(Media Queries)和流式布局(Fluid Grids),可以确保后台在桌面、平板和手机上都能良好展示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值