購買飼料
如約翰在鎮上,沿著公路開車回家,他的家離起點有e公里。他順便準備買k噸飼料回家。運送飼料是要花油錢的,如果他的車上有x噸飼料,行駛一公里需要x^2元,行駛d公里就 需要dx^2元。約翰可以從n家商店購買飼料,所有商店都在公路邊上,第i家店距離起點xi公里,飼料單價為每噸ci元,庫存為fi噸。
約翰可以選擇在任意商店裡購買任意多的飼料,只要那家店的還有貨就可以了。保證所有商店的飼料庫存之和不會少於k,為了帶k噸飼料回家,約翰最少的花費是多少呢?
舉個例子,假設有三家商店,情況如下所示:
座標 x = 1 x = 3 x = 4 e = 5
庫存 1 1 1
單價 1 2 2
如果約翰要買2噸飼料回家,那麼他的最好選擇是在離家較近的兩家商店購買飼料,則花在路上的錢是1 + 4 = 5,花在商店的錢是2 + 2 = 4,共需要9元。
第一行:三個用空格分開的整數:k,e和n,1 ≤ k ≤ 10000,1 ≤ e,n ≤ 500
第二行到n + 1行:第i + 1行有三個用空格分開的整數乙個整數: xi, fi和ci, 0 < xi < e, 1 ≤ fi ≤ 10000,1 ≤ ci ≤ 10,000,000
第一行:單個整數,表示約翰購買和運送飼料的最小花費
正解=動歸+佇列優化
先考慮無優化的dp
狀態:f[i][j] 表示 在 i 這個位置且車上有 j 噸飼料至少要多少錢
轉移: f[i+1][j]=f[i][j-g]+c[i]*g+j*j*( x[i+1]-x[i] )( 0<=g<=f[i] )
輸出:f[n+1][k](設n+1為家)
顯然o(n*k*f)必然會tle
考慮優化
設 g『=j-g 則 j-g』=g( 0<=g<=f[i] ),
g 增加 ,g『 減少,
則上面的 f[i+1][j] 可表示成
f[i+1][j]=f[i][ g』 ]+c[i]*( j-g' )+j*j*( x[i+1]-x[i])
=f[i][ g』 ]+ c[i]*j - c[i]*g' +j*j*( x[i+1]-x[i] )
( j-f[i] <= g' <=j ) (g' 必然小於 j,無需處理)
顯然 c[i]*j 和 j*j*( x[i+1]-x[i] ) 為定值,
f[i+1][j]的值由 f[i][ g』 ] - c[i]* g' 決定,
可構造佇列q(元素為 g『 ):
從 0 到 f[i]一一進隊(j)
如果 j-q.front()>f[i] 出隊
j 進隊,保持佇列遞減
f[i+1][j]=f[i][q[head] ]+ c[i]*( j-q[head] ) - c[i]*g' +j*j*( x[i+1]-x[i] )
複雜度o(n*k)不會 t 了- =(orz ak god)
**如下:
1 #include2 #include3 #include4 #includeview code5 #include6 #include7
#define ll long long
8#define inf 99999999999ll
9struct
cowa[509
];12
bool cmp(const cow&x,const cow&y)
15int
k,e,n,head,tail;
16long
long f[509][10009
];17
int q[10009
];18
intmain() 36}
37 printf("
%lld
",f[n+1
][k]);
38 }
修剪草坪
在去年贏得了小鎮的最佳草坪比賽後,約翰變得懶惰了,再也沒有修剪過草坪了。現在,新一輪的比賽又開始了,約翰希望能夠再次奪冠。然而,約翰的草坪非常髒亂,因此,約翰需要讓他的奶牛來完成這項工作。約翰有n頭奶牛,平時排成一條直線,編號為1到n。每只奶牛的能力是不同的,第i頭奶牛的能力為ei。靠在一起的奶牛很熟悉,所以如果安排編號連續的k + 1頭奶牛在一起工作,她們就會密謀罷工。因此,約翰需要你的幫助。如何挑選奶牛,才能使她們的工作能力之和最高,而且不會罷工呢?
第一行:兩個用空格隔開的整數:n和k,1 ≤ n ≤ 105,1 ≤ k ≤ n
第二行到n + 1行:第i + 1行有乙個整數,表示第i頭牛的能力ei,1 ≤ ei ≤ 109
第一行:單個整數,表示最大的工作能力之和
和上題一樣想考慮裸dp
預處理: sum[i] 表示從第一頭奶牛到第 i 頭奶牛的能力和,
狀態: f[i]表示到到第i頭可得到的最大能力值和,
轉移: f[i]=f[j]+sum[i]-sum[j+1]
比上一題簡單,很容易看出sum[i]是個定值,
按 f[j]-sum[j+1] 做單調佇列即可,
ps.注意 k=1 時的情況
**如下:
1 #include2 #include3 #include4 #includeview code5 #include6 #include7
#define inf 99999999
8#define max(x,y) if(y>x) x=y
9#define ll long long
10using
namespace
std;
11 ll head,tail,q[100001],p[100001],f[100001],n,k,sum[100001
],ans;
12int
main()
19 head=1
;20 tail=0;21
for(ll i=1;i<=k;i++)
28for(ll i=k+1;i<=n;i++)
36 printf("
%lld
",ans);
37 }
Usaco 2011 Open 修剪草坪
傳送門 題目描述 在一年前贏得了小鎮的最佳草坪比賽後,fj 變得很懶,再也沒有修剪過草坪。現在,新一輪的最佳草坪比賽又開始了,fj 希望能夠再次奪冠。然而,fj 的草坪非常髒亂,因此,fj 只能夠讓他的奶牛來完成這項工作。fj 有 n 1 n 100 000 n 1 n 100,000 n 1 n ...
2202 修剪草坪
在一年前贏得了小鎮的最佳草坪比賽後,約翰變得懶惰了,再也沒有修剪過草坪。現在,新一輪的比賽又開始了,約翰希望能夠再次奪冠。然而,約翰家的草坪非常髒亂,因此,約翰需要讓他的奶牛來完成這項工作。約翰家有n頭奶牛,排成一直線,編號為1到n。每只奶牛的能力是不同的,第i頭奶牛的能力為ei。靠在一起的奶牛很熟...
小學期 修剪草坪
有乙個n m的草坪 1 n,m 100 草坪中的草原來的高度都是100。現在使用割草機修剪草坪,來得到各種各樣的圖案。割草機只 能橫著或者豎著割草。每次割草都會先設定乙個高度,割完之後會把比設定高度高的草都割成設定的高度。比如草原來是5 2 8,設定高度為4,那麼割完之後就變成了4 2 4。現在給出...