先恭喜一下 vijos 升級成2,0 版本 恭喜恭喜。
描述
“妹妹揹着洋娃娃,走到花園看櫻花” – 我整個人都Hello kitty了。
好了,閒話就說到這裏,已知:這是一個1×N的花園(雖然比較奇怪),被分成了N個格子,每個格子裏有一種神奇的櫻花(我也不知道爲什麼神奇,反正洋娃娃看着高興),看到第i個格子上的花洋娃娃會得到不同的滿足度Ci(每個花的滿足度只被計算一次)。現在妹妹會揹着洋娃娃從任意格子走進花園,當然從第i個格子進去會消耗Di個單位的滿足度,然後遊歷花園,在一個格子向右走需要耗費R個單位的滿足度,向左走需要耗費L個單位的滿足度,最後從第i個格子出花園又要耗費Fi個單位的滿足度。
接下來,我們需要設計一套遊歷方案,使得最終獲得的總滿足度最高(太低的話洋娃娃會……)格式
輸入格式
第一行依次給出三個正整數N,L,R。
第二行有N個整數,第i個數爲Di。
第三行有N個整數,第i個數爲Fi。
第四行有N個整數,第i個數爲Ci。輸出格式
僅需要輸出一行包括一個整數,表示最大獲得的滿足度爲多少。
首先,這道題目是一道動規題,一開始呢,根本想不到怎麼動規。 可能一看到動規的題目,我就想用一個二維數組f[i,j]來 表示 從第 i 個點到第j 個點的最大滿意值,會想到f[i,j]與f[i,j-1], f[i,j+1], f[i+1,j],f[i-1,j] 有聯繫,好吧,只能說我還沒弄清楚。
看到這道題的題解後,發現這裏的dp不是直接dp f[i,j];
具體分析:
有 i,j 兩點, 設起點爲i 終點爲 j,且i<j, 因爲滿意度只能計算一次,則從i走到j共有以下幾種走法:
1.直接從i 走到j 。
2.從i向左走再走回i再走到j(說不定能多拿一點滿意度)。
3.從i向右走到j再向右走再向左走回到j(理由同上)。
4. 2點和3點綜合,從i點向左走再走回i,然後從i向右走到j再向右走再向左走回到j。(理由同上)。
如果直接算的話,會很麻煩,所以我們弄一個預處理:
弄一個數組q[i],表示由1 到i 的滿意度總和(不計代價)。
兩個數組:
一個z[i],表示 由i向左走再走回來能夠多拿的滿意度(計代價)。
一個y[i],與z[i]一樣,只不過方向向右。
若 i 爲起點 j 爲終點
我們可以知道 如果 i>j 則 s[i,j]=q[i]-q[j-1]+y[i]+z[j]-(i-j)*l-d[i]-f[j]
如果i<j s[i,j]=q[j]-q[i-1]+y[j]+z[i]-(j-i)*r-d[i]-f[j]
我們不確定 y和z 是否能夠加上去,如果他爲負,我們我不能加,否則不是最優解。
判斷的話就有點麻煩,所以我們可以這樣:
若 z[i]or y[i]<0 就 把他賦值爲0。
這樣就算爲負我們加上去 也沒問題了。
程序:
program p1627aaa; type arr=array[0..1010]of longint; arrr=array[0..1010,0..1010]of longint; var i,j,k,l,m,n,r,maxx:longint; s:arrr; q,c,d,f,z,y:arr; function max(a,b:longint):longint; begin if a>b then exit(a) else exit(b); end; begin maxx:=-maxlongint; read(n,l,r); for i:=1 to n do read(d[i]); for i:=1 to n do read(f[i]); for i:=1 to n do read(c[i]); for i:=1 to n do for j:=1 to n do s[i,j]:=-maxlongint; for i:=1 to n do q[i]:=q[i-1]+c[i]; for i:=1 to n do begin z[i]:=-maxlongint; y[i]:=-maxlongint; end; for i:=1 to n do begin for j:=1 to i do begin z[i]:=max(z[i],q[i]-q[j-1]-(i-j)*(l+r)-c[i]); end; if z[i]<0 then z[i]:=0; end; for i:=1 to n do begin for j:=n downto i do begin y[i]:=max(y[i],q[j]-q[i-1]-(j-i)*(l+r)-c[i]); end; if y[i]<0 then y[i]:=0; end; for i:=1 to n do for j:=1 to n do begin if i>j then s[i,j]:=q[i]-q[j-1]+y[i]+z[j]-(i-j)*l-d[i]-f[j] else s[i,j]:=q[j]-q[i-1]+y[j]+z[i]-(j-i)*r-d[i]-f[j]; if s[i,j]>maxx then maxx:=s[i,j]; end; write(maxx); end.