列表

详情


NC24197. [USACO 2018 Dec P]Balance Beam

描述

Bessie为了存钱给她的牛棚新建一间隔间,开始在当地的马戏团里表演,通过在平衡木上小心地来回走动来展示她卓越的平衡能力。

Bessie能够通过表演赚到的钱取决于她最终成功跳下平衡木的位置。平衡木上从左向右的位置记为0,1,…,N+1。如果Bessie到达了位置0或是N+1,她就会从平衡木的一端掉下去,遗憾地得不到报酬。

如果Bessie处在一个给定的位置k,她可以进行下面两项中的任意一项:

1. 投掷一枚硬币。如果背面朝上,她前往位置k−1,如果正面朝上,她前往位置k+1(也就是说,每种可能性1/2的概率)。

2. 跳下平衡木,获得f(k)的报酬(1≤f(k)≤10^9)。

Bessie意识到她并不能保证结果能够得到某一特定数量的报酬,这是由于她的移动是由随机的掷硬币结果控制。然而,基于她的起始位置,她想要求出当她进行一系列最优的决定之后,她能够得到的期望报酬(“最优”指的是这些决定能够带来最高可能的期望报酬)。例如,如果她的策略能够使她以1/2的概率获得10的报酬,1/4的概率获得8的报酬,1/4的概率获得0的报酬,那么她的期望报酬为加权平均值10(1/2)+8(1/4)+0(1/4)=7

输入描述

输入的第一行包含N(2≤N≤10^5)。以下N行包含f(1)…f(N).

输出描述

输出N行。第i行输出10^5乘以Bessie从位置ii开始使用最优策略能够获得的报酬的期望值,向下取整。

示例1

输入:

2
1
3

输出:

150000
300000

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 24ms, 内存消耗: 2964K, 提交时间: 2020-09-07 06:52:37

#include <bits/stdc++.h>
typedef long long ll;

inline void read(ll&x){
	char c11=getchar();x=0;while(!isdigit(c11))c11=getchar();
	while(isdigit(c11))x=x*10+c11-'0',c11=getchar();
}

const int N=101000,bs=1e5;
int n,tp;

struct vec{
	int x;ll y;
	inline vec(){}
	inline vec(const int&X,const ll&Y):x(X),y(Y){}
	friend inline vec operator - (const vec&A,const vec&B) {return vec(A.x-B.x,A.y-B.y);}
	friend inline ll operator * (const vec&A,const vec&B) {return A.x*B.y-A.y*B.x;}
}p,st[N];

void push(vec p){
	while(tp&&(p-st[tp])*(st[tp]-st[tp-1])<=0)--tp;
	st[++tp]=p;
}

int main(){
	scanf("%d",&n);vec p;
	for(int i=1;i<=n;++i)p.x=i,read(p.y),p.y*=bs,push(p);
	push(vec(n+1,0));
	for(int i=1,j=0;i<=n;++i){
		while(j<tp&&st[j].x<i)++j;
		if(st[j].x==i)printf("%lld\n",st[j].y);
		else printf("%lld\n",((st[j].x-i)*st[j-1].y+(i-st[j-1].x)*st[j].y)/(st[j].x-st[j-1].x));
	}return 0;
}

C++14(g++5.4) 解法, 执行用时: 28ms, 内存消耗: 4364K, 提交时间: 2020-09-07 09:19:19

#include <bits/stdc++.h>
const int N=1e5;
int n,cnt;

struct node{
	int x;
	long long y;
	node(int a=0,long long b=0){
		this->x=a;
		this->y=b;
	}
	node operator - (const node &a) {return node(x-a.x,y-a.y);}
	long long operator * (const node &a) {return x*a.y-y*a.x;}
}jia,s[N+10];

void push(node nw){
	while(cnt&&(nw-s[cnt])*(s[cnt]-s[cnt-1])<=0) --cnt;
	s[++cnt]=nw;
}

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i) scanf("%lld",&jia.y),jia.x=i,jia.y*=N,push(jia);
	push(node(n+1,0));
	for(int i=1,j=0;i<=n;++i){
		while(j<cnt&&s[j].x<i) ++j;
		if(s[j].x==i) printf("%lld\n",s[j].y);
		else printf("%lld\n",((s[j].x-i)*s[j-1].y+(i-s[j-1].x)*s[j].y)/(s[j].x-s[j-1].x));
	}return 0;
}

上一题