乙個長度為n
n的數列,每次可以選擇前面任意乙個位置i
i跳到那裡,價值為ai×
(i−a
i×(
i−你所在的位置)
)。求跳到n
n的最大價值。
證明:每次選擇max
max 其中j
j 表示你所在的位置。
先設起點是0。那麼直接單調佇列記錄最大值即可。那麼假設i
i是最大價值的點,但是最優解應該先跳到j
j,且下一次將跳到k
k,且j
<
i<
i那麼從0跳到j
j的價值是j×a
jj×a
j,跳到i
i的價值是i×a
ii×a
i。從j
j跳到k
k的價值是(k−
j)ak
(k−j
)ak
,從ii
跳到kk
的價值是(k−
i)ak
(k−i
)ak
。明顯從j
j跳到k
k的價值比從i
i跳到k
k的價值大(i−
j)ak
(i−j
)ak
。那麼如果i×a
i−j×
aj>(i
−j)a
ki×a
i−j
×aj
>(i
−j)a
k,那麼跳到i
i是更合法的。
移項,只要i×a
i>(i
−j)a
k+j×
aji×
ai>(i
−j)a
k+j
×aj
就更合法。設t=
max(
ak,a
j)t=
max(
ak,
aj)
,有(i−j
)ak+
j×aj
≤(i−
j)t+
j×t(
i−j)
ak+
j×aj
≤(i
−j)t
+j×t
不等號右側合併同類項得(i−
j)ak
+j×a
j≤(i
−j+j
)t(i
−j)a
k+j
×aj
≤(i−
j+j)
t,即(i−
j)ak
+j×a
j≤ti
(i−j
)ak
+j×a
j≤t
i因為a
i>ta
i>
t(已經假設i
i是最大價值的點),所以i×a
i>ti
i×ai
>ti
所以有i×a
i>ti
≥(i−
j)ak
+j×a
ji×a
i>ti
≥(i−
j)ak
+j×
aj證畢。
#include
#include
#define mp make_pair
using
namespace std;
int n,ans,x,y,last;
dequeint,
int>
> q;
intmain()
while
(q.size()
)printf
("%d\n"
,ans)
;return0;
}
jzoj4249 遊戲 貪心
0 n 0 sim n 0 n的點,從i ii移動到j jj獲得aj j i a j j i aj j i 的價值。求最大價值。考慮貪心,每次移動到往後a ia i ai 最大的點。證明 反證明 我們假設有一種情況i ij a jaj 但是之間移動到j jj比先移動到i ii更優。但是若我們先移動到...
JZOJ4249 遊戲 貪心
乙個長度為n n的數列,每次可以選擇前面任意乙個位置i i跳到那裡,價值為ai i a i i 你所在的位置 求跳到n n的最大價值。證明 每次選擇max max 其中j j 表示你所在的位置。先設起點是0。那麼假設i i是最大價值的點,但是最優解應該先跳到j j,且下一次將跳到k k,且j i i...
動態規劃 貪心 JZOJ 4249 遊戲
乙個人從起點0 00出發。他現在如果在i ii,那麼如果跳到j jj,那麼獲得的價值為 j i a j j i a j j i aj 求剛好落到終點n nn的最大可獲得的價值。剛開始看到就想到o n 2 的d po n 2 的dp o n2 的 dp,結果看了下資料發現只能拿60 6060 分,正解...