BZO1911 ||洛谷P3628 [APIO2010]特别行动队【斜率优化DP】

Time Limit: 4 Sec Memory Limit: 64 MB

Description

在这里插入图片描述

Input

在这里插入图片描述

Output

在这里插入图片描述

HINT

在这里插入图片描述


题目分析
斜率优化DP–详解

首先容易想到一个简单的 O ( n 2 ) O(n^2) O(n2)算法
d p [ i ] dp[i] dp[i]表示 i i i个士兵分组能得到的最大战斗力
d p [ i ] = m a x (   d p [ j ] + a ∗ ( s u m [ i ] − s u m [ j ] ) 2 + b ∗ ( s u m [ i ] − s u m [ j ] ) + c   ) dp[i]=max(\ dp[j]+a*(sum[i]-sum[j])^2+b*(sum[i]-sum[j])+c\ ) dp[i]=max( dp[j]+a(sum[i]sum[j])2+b(sum[i]sum[j])+c )

然后把平方拆开,移项
d p [ j ] + a ∗ s u m [ j ] 2 − b ∗ s u m [ j ] = 2 a ∗ s u m [ i ] ∗ s u m [ j ] − a ∗ s u m [ i ] 2 − b ∗ s u m [ i ] − c + d p [ i ] dp[j]+a*sum[j]^2-b*sum[j]=2a*sum[i]*sum[j]-a*sum[i]^2-b*sum[i]-c+dp[i] dp[j]+asum[j]2bsum[j]=2asum[i]sum[j]asum[i]2bsum[i]c+dp[i]
d p [ j ] + a ∗ s u m [ j ] 2 − b ∗ s u m [ j ] dp[j]+a*sum[j]^2-b*sum[j] dp[j]+asum[j]2bsum[j] y y y s u m [ j ] sum[j] sum[j] x x x 2 a ∗ s u m [ i ] 2a*sum[i] 2asum[i]为斜率进行斜率优化即可

注意此题所求是最大值,单调队列维护的是斜率单调递减的上凸壳


#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long lt;
typedef double dd;
#define sqr(x) ((x)*(x))

lt read()
{
    lt f=1,x=0;
    char ss=getchar();
    while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
    while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
    return f*x;
}

const int maxn=2000010;
lt n,a,b,c;
lt sum[maxn],dp[maxn];
int q[maxn],ll,rr;

lt qans(int i,int j){ return dp[j]+a*sqr(sum[j])-b*sum[j]-2*a*sum[i]*sum[j]+a*sqr(sum[i])+b*sum[i]+c;}
dd calc(int j1,int j2)
{
    lt ty=(dp[j2]+a*sqr(sum[j2])-b*sum[j2])-(dp[j1]+a*sqr(sum[j1])-b*sum[j1]);
    lt tx=sum[j2]-sum[j1];
    return (dd)ty/(dd)tx;
}

int main()
{
    n=read();a=read();b=read();c=read();
    for(int i=1;i<=n;++i) 
    {
        int x=read();
        sum[i]=sum[i-1]+x;
    }
    
    ll=rr=1;
    for(int i=1;i<=n;++i)
    {
    	while( ll<rr && calc(q[ll],q[ll+1]) >= 2*a*sum[i] ) ++ll;
    	dp[i]=qans(i,q[ll]);
    	while( ll<rr && calc(q[rr-1],q[rr]) <= calc(q[rr],i) ) --rr;
    	q[++rr]=i;
    }
    printf("%lld",dp[n]);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在QNX操作系统中,可以按照以下步骤设置Telnet登录密码: 1. 打开/etc/inetd.conf文件,可以使用任何文本编辑器打开该文件,例如: ``` vi /etc/inetd.conf ``` 2. 找到以下行: ``` telnet stream tcp nowait root /usr/sbin/telnetd telnetd ``` 如果该行不存在,则需要添加它。如果已经存在,则跳过此步骤。 3. 在该行的末尾添加以下选项: ``` -a <username> ``` 其中,<username>表示要使用的用户名。例如,如果要使用用户名"myuser",则可以将该行修改为: ``` telnet stream tcp nowait root /usr/sbin/telnetd telnetd -a myuser ``` 这将设置Telnet登录用户名为"myuser",但是仍然没有设置密码。 4. 打开/etc/passwd文件,可以使用任何文本编辑器打开该文件,例如: ``` vi /etc/passwd ``` 5. 在该文件的相应行中为之前设置的Telnet登录用户名设置密码。可以使用以下命令生成密码哈希值: ``` mkpasswd -p <password> ``` 其中,<password>表示要设置的密码。例如,如果要设置密码为"mypassword",则可以使用以下命令: ``` mkpasswd -p mypassword ``` 该命令将生成一个密码哈希值,类似于"$1$7CxmylqX$BZo9NcOu5V3xw6BYt7Z6K1"。将该哈希值复制到密码文件的相应行中。 6. 保存并关闭文件。 7. 重新启动inetd服务,以使配置文件生效。可以使用以下命令重启服务: ``` svc -t /etc/svc/inetd ``` 现在,你的QNX系统已经设置了Telnet登录密码。当用户连接到服务器时,他们将被要求输入用户名和密码才能登录。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值