Description
阿明是一名推销员,他奉命到螺丝街推销他们公司的产品。螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户。螺丝街一共有NN家住户,第ii家住户到入口的距离为S_iSi米。由于同一栋房子里可以有多家住户,所以可能有多家住户与入口的距离相等。阿明会从入口进入,依次向螺丝街的XX家住户推销产品,然后再原路走出去。
阿明每走11米就会积累11点疲劳值,向第ii家住户推销产品会积累A_iAi点疲劳值。阿明是工作狂,他想知道,对于不同的XX,在不走多余的路的前提下,他最多可以积累多少点疲劳值。
Solution
考虑我们如何将答案最大化:对于每个x,一定是选择(一个最大的s)+(x-1个最大的a)或者x个最大的a,可以使答案最优
我们先把数组按照a排序
我们用sum[i]表示a数组的前i项的和,lu[i]表示s数组的前i项的最大值,k[i]表示a[i]*2+s[i]后i项的最大值,
对于每个x,他的答案就是max(sum[x]+lu[i]*2,sum[x-1]+k[x])
Code
#include <bits/stdc++.h> using namespace std; int n; int sum[100010], lu[100010], k[100010]; struct emmm { int s, v; } a[100010]; bool cmp(emmm a, emmm b) { return a.v > b.v; } int main() { ios::sync_with_stdio(false); cin >> n;//输入n for (int i = 1;i <= n; i++) cin >> a[i].s; for (int i = 1;i <= n; i++) cin >> a[i].v; sort(a + 1, a + n + 1, cmp); for (int i = 1;i <= n; i++) { sum[i] = sum[i - 1] + a[i].v; lu[i] = max(lu[i - 1], a[i].s); } for (int i = n; i >= 1; i--) k[i] = max(k[i + 1], a[i].s * 2 + a[i].v); for (int i = 1;i <= n; i++) cout << max(sum[i] + lu[i] * 2, sum[i - 1] + k[i]) << endl; return 0; }