賣飼料 單調佇列優化dp

2022-08-17 14:24:11 字數 1189 閱讀 3873

約翰開車來到鎮上,他要帶k噸飼料回家。運送飼料是需要花錢的,如果他的車上有x噸飼料,每公里就要花費x^2元,開車d公里就需要d* x^2元。約翰可以從n家商店購買飼料,所有商店都在乙個座標軸上,第i家店的位置是xi,飼料的售價為每噸ci元,庫存為fi。  

約翰從座標x=o開始沿座標軸正方向前進,他家在座標x=e上。為了帶k噸飼料回家, 約翰最少的花費是多少呢? 

假設所有商店的庫存之和不會少於k。  

舉個例子,假設有三家商店,情況如下所示:  

座標 x=1 x=3 x=4 e=5  

庫存 1     1     1  

售價 1     2     2  

如果k=2,約翰的最優選擇是在離家較近的兩家商店購買飼料,則花在路上的錢是1+4=5,花在商店的錢是2+2=4,共需要9元。 

$dp[i][j]$表示到了$i$帶有$j$噸飼料的最少花費。(注意此時i商店還沒有買

)在每個商店我們可以選擇買或者不買,列舉$i-1$之前帶有的飼料$k$,那麼$dp[i]][j]=min(dp[i-1][k]+j*j*(d[i]-d[i-1])+(j-k)*c[i])$

整理一下:$dp[i][j]=min(dp[i-1][k]-k*c[i]+j*j*(d[i]-d[i-1])+j*c[i])$

單調佇列維護使dp[i-1][k]最小的 k轉移即可。

#includeusing

namespace

std;

typedef

long

long

ll;const

int k=10010

;const

int n=510

;ll f[n][k];

intk,hm,n;

struct

farm

a[n];

ll d[n];

bool

cmp(farm a,farm b)

intmain()

;

for(int i=1;i<=n;i++)

d[i]=a[i].x-a[i-1

].x;

memset(f,

0x3f,sizeof

(f));

f[0][0]=0

;

for(int i=1;i<=n;i++)

}cout

<}

單調佇列 優化DP

佇列元素保持單調遞增 減 而保持的方式就是通過插隊,把隊尾破壞了單調性的數全部擠掉,從而使佇列元素保持單調。單調佇列的作用 優化dp。許多單調佇列優化的dp可以使複雜度直接降維,下面就以最簡單的一道題為例 在某兩座城市之間有 n 個烽火台,每個烽火台發出訊號都有一定代價。為了使情報準確地傳遞,在連續...

單調佇列優化dp

形如f i max wi的問題都可以用單調佇列優化。例題 板題 注意乙個地方 求完所有的f後 ans不是f n 而是後面的一段字尾的f 注意字尾的左端點。很顯然是rmq問題 計算字首和sum i 對於固定的右端點 i,我們想讓答案最大等價於max,可以用個單調佇列維護。但是隨便乙個資料結構直接on ...

DP 單調佇列優化

使用單調佇列優化的題目具有這樣的特點,他需要我們維持一段區間內的某個最優值,這個區間是隨著遍歷的順序變化的,但是其變化一定具有這樣的特性,也即維持的區間左右端點一定是單調遞增的,而不能出現回流的現象,否則我們在維持佇列單調性過程中剪枝的資料可能是新的區間中的最大值。維持區間最優值的方法有很多,例如靜...