P2672 推销员
思路:贪心思想就是让疲惫值大的排在前面。先说最后你要输出的
。当你访问i的时候你这个时候需要考虑的是 我访问到i就可以吗?它是最大值嘛?还是我需要再往后看看呢。描述成式子max(前i人的疲惫值得和+当前距离的二倍,前i-1人的疲惫和+后面i个人的最大的 (疲惫值+距离*2))。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#include <algorithm>
#include <iomanip>
#include <map>
#include <queue>
#include <vector>
#include <set>
const int inf = 0x3f3f3f3f;//1061109567
typedef long long ll;
using namespace std;
/*const int N = 1001000;
ll n, m,k,ans; ll sum[N+5];
int lowbit(int x) { return x & (-x); }
//修改
void add(int p, int x)
{
for (int i =p; i <=m; i += lowbit(i)) //x为更新的位置,y为更新后的数,n为数组最大值
sum[i] += x;
}
//查询
int getsum(int x)
{
int ans = 0;
for (int i = x; i>0; i -= lowbit(i))
ans += sum[i];
return ans;
}*/
struct node
{
int s, v;
}a[100100];
int q[100100], h[100100], s[100100];
int n;
//h[i]表示 2*a[i].v+a[i].v的最大值
int cmp(node a, node b)
{
return a.v > b.v;
}
int main()
{
cin >> 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 + 1 + n, cmp);
for (int i = n; i >= 1; i--)
{// 表示a[i]*2+s[i]后i项的最大值
h[i] = max(h[i + 1], 2 * a[i].s + a[i].v);
}
for (int i = 1; i <= n; i++)
q[i] = q[i - 1] + a[i].v;// 前i-1项的疲惫和
for (int i = 1; i <= n; i++)// 前i项 最大的距离s
s[i] = max(s[i - 1], a[i].s);
for (int i = 1; i <= n; i++)
cout << max(q[i - 1] + h[i], q[i] + 2 * s[i]) << endl;
}