usaco 購買飼料 修剪草坪

2022-06-02 10:09:10 字數 3205 閱讀 7830

購買飼料

如約翰在鎮上,沿著公路開車回家,他的家離起點有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 #include

5 #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 }

view code

修剪草坪

在去年贏得了小鎮的最佳草坪比賽後,約翰變得懶惰了,再也沒有修剪過草坪了。現在,新一輪的比賽又開始了,約翰希望能夠再次奪冠。然而,約翰的草坪非常髒亂,因此,約翰需要讓他的奶牛來完成這項工作。約翰有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 #include

5 #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 }

view code

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。現在給出...