題目大意
奶牛Bessie在一條橫樑上。橫樑有個位置,分別爲。
Bessie最終得到的錢和她跳下橫樑的位置有關。如果Bessie到達位置或位置,那麼Bessie將從橫樑的一端掉下,得到元錢。
當Bessie在位置時,她可以決定做以下兩件事之一:
- 等概率移動到位置或。
- 跳下橫樑,得到元錢。
請求出Bessie從的每個位置開始,按最優策略期望能得到的錢。
輸入格式
第一行,一個整數。接下來行每行一個整數。
輸出格式
行,第行輸出從位置開始能得到的錢,乘以後下取整。
題解
對於位置,需要求出Bessie到達該位置時,是移動還是跳下(對於位置與必須跳下)。
對於如圖所示的情形,假設紅色的點選擇跳下,藍色的點選擇移動。
設爲從位置開始能得到的錢,則有如下方程組:
解得
即:在平面上,點在與連接構成的線段上!
所以,要想使所有最大,需要求出點的上凸殼,
然後對於在凸殼上的點選擇跳下,其他點選擇移動即可。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=100005;
int n,x[N];
ll f[N];
int main(){
freopen("balance.in","r",stdin);
freopen("balance.out","w",stdout);
scanf("%d",&n);x[0]=1;
for(int i=1;i<=n;i++)scanf("%lld",&f[i]);
for(int i=1;i<=n+1;i++){
int a=x[x[0]],b=x[x[0]-1];
while(x[0]>1&&(f[i]-f[a])*(i-b)>=(f[i]-f[b])*(i-a)){
--x[0];
a=x[x[0]],b=x[x[0]-1];
}
x[++x[0]]=i;
}
for(int i=1;i<x[0];i++){
int v=x[i],u=x[i+1];
for(int j=v;j<u;j++)if(j){
ll w=f[v]*(u-j)+f[u]*(j-v);
printf("%lld\n", (ll)floor(w*100000.0/(u-v)) );
}
}
return 0;
}