推销员
题目描述
阿明是一名推销员,他奉命到螺丝街推销他们公司的产品。螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户。螺丝街一共有NNN家住户,第iii家住户到入口的距离为SiS_iSi米。由于同一栋房子里可以有多家住户,所以可能有多家住户与入口的距离相等。阿明会从入口进入,依次向螺丝街的XXX家住户推销产品,然后再原路走出去。
阿明每走111米就会积累111点疲劳值,向第iii家住户推销产品会积累AiA_iAi点疲劳值。阿明是工作狂,他想知道,对于不同的XXX,在不走多余的路的前提下,他最多可以积累多少点疲劳值。
输入输出格式
输入格式:
第一行有一个正整数NNN,表示螺丝街住户的数量。
接下来的一行有NNN个正整数,其中第iii个整数SiS_iSi表示第iii家住户到入口的距离。数据保证S1≤S2≤…≤Sn<108S_1≤S_2≤…≤S_n<10^8S1≤S2≤…≤Sn<108。
接下来的一行有NNN个正整数,其中第iii个整数AiA_iAi表示向第iii户住户推销产品会积累的疲劳值。数据保证Ai<1000A_i<1000Ai<1000。
输出格式:
输出NNN行,每行一个正整数,第i行整数表示当X=iX=iX=i时,阿明最多积累的疲劳值。
分析:
我们先把数组按照a排序
我们用sum[i]表示a数组的前i项的和,q[i]表示s数组的前i项的最大值,h[i]表示a[i]*2+s[i]后i项的最大值,对于每个x,他的答案就是max(sum[x]+2*q[x],sum[x-1]+h[x])
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; struct home{ int s,v; }a[100010]; int q[100010]; int h[100010],qm[100010]; int n; bool cmp(home a,home b) { return a.v>b.v; } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d",&a[i].s); } for (int i=1;i<=n;i++) { scanf("%d",&a[i].v); } sort(a+1,a+1+n,cmp); for (int i=n;i>=1;i--) { h[i]=max(h[i+1],2*a[i].s+a[i].v); } for (int i=1;i<=n;i++) { qm[i]=max(qm[i-1],a[i].s); } for (int i=1;i<=n;i++) q[i]=q[i-1]+a[i].v; for (int i=1;i<=n;i++) { printf("%d\n",max(q[i-1]+h[i],q[i]+2*qm[i])); } }