1. 程式人生 > >洛谷P3195 玩具裝箱TOY

洛谷P3195 玩具裝箱TOY

區間 有意義 game 上下 sca 無法 通過 namespace its

題目大意:

有n個數,要將他們分成若幹段,每一段的cost定義為: cost=r-l+ΣCk (k∈[r,l]) 該段的最終花費是:(cost-L)^2; 給出L,n,C(1~n),總共的最小花費。

分析:

dp方程極容易想出來: f[i]=max(f[j]+(sum[i]-sum[j]+i-j-1-L)^2) 其中sum[i]表示c(1~i)的和。因為取的這一段數從j+1開始,所以i-j-1(題目中i-j並不是區間長度!沒有再加1)

O(n^2)直接掛掉。

因為狀態O(n)已經非常不錯,無法再優化了。所以考慮能不能優化轉移的O(n)。

將表達式展開:

f[i]=f[j]+(sum[i]-sum[j]+i-j-1-L)^2

令a[k]=sum[k]+k;x[k]=a[k]+1+ f[i]=f[j]+(a[i]-x[j])^2

f[i]=f[j]+x[j]^2-2a[i]x[j]+a[i]^2

對於給定的i,a[i]^2是一個定值,所以當做常數先不用管,但是記得最後加上!

令y[k]=f[k]+x[k]^2; f[i]=y[j]-2a[i]x[j]

移項: y[j]=2a[i]x[j]+f[i]

對於給定的i,我們需要循環所有的j。 對於一個j,我們已經知道了x[j],y[j]。 將它看作一個點,所有的j構成一個點集,橫坐標x[j],縱坐標y[j]

而對於給定的i,2a[i]是一個定值,看做斜率,而目標f[i]則是截距,所以要在j的點集之中找到一個點使得這條直線截距最小,本質是將y=2a[i]x的直線平移。

可以發現這些最優解的點必定在邊界上。並且發現,斜率是單增的,而x一定也是單增的。所以可以維護一個左上下凸殼。

因為斜率單增,所以若一個點此時不是最優解,那麽以後一定也不是最優解,可以直接從頭pass掉;每次新增一個點,都要保證這是一個凸包,通過斜率要來從尾pass掉。

所以可以用單調隊列維護!單調,在這裏是指隊列中的元素,每相鄰兩個元素所代表的點連成的線,其斜率是單調遞增的。因為斜率都是正數,所以也就是畫出來是一個左上凸包。

註意,隊列中至少要有一個0號元素不能出隊!這裏第一個空位置是有意義的。否則就不存在線和斜率了。所以手寫隊列時,開始hd=tl=0,while判斷中hd<tl 保證一定至少有一個元素,並且這個元素不會被其他元素替代。詳見代碼。

具體步驟:

1.前綴和預處理

2.循環i,先刪除隊首,再更新答案,再更新隊列。

3.輸出f[n] GAME OVER

代碼:

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
const int N=50000+10;
int n,L;
long long f[N];
long long sum[N];
int q[N],hd,tl;
long long a(int i)
{
    return sum[i]+i;
}
long long x(int i)
{
    return sum[i]+i+L+1;
}
long long y(int i)
{
    return x(i)*x(i)+f[i];
}
double slope(int a,int b)
{
    return  ((double)y(b)-y(a))/((double)x(b)-x(a));
}//一堆函數
int t;
int main()
{
    scanf("%d%d",&n,&L);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&t);
        sum[i]=sum[i-1]+t;
    }
    hd=0,tl=0;
    for(int i=1;i<=n;i++)
    {
        while(hd<tl&&slope(q[hd],q[hd+1])<2*a(i)) hd++;//刪除
        f[i]=y(q[hd])-2*a(i)*x(q[hd])+a(i)*a(i);
        while(hd<tl&&slope(q[tl-1],q[tl])>slope(q[tl-1],i)) tl--;
        q[++tl]=i;//更新
    }
    printf("%lld",f[n]);
    return 0;
}

總結:

1.一個題能用斜率優化,必然能出現y=kx+b 線性形式,其中k是定值,x,y構成點集,b是目標值。

2.一個凸包能用單調隊列優化的條件應該滿足:

(1)查詢的斜率單調 (2)插入的點橫坐標有單調性 (否則要用平衡樹、set)

洛谷P3195 玩具裝箱TOY