https://www.luogu.org/problemnew/show/P2672
题意:中文
题解:这题被学姐放在DP里了,然鹅我实在想不到O(n)的转移,想了半天,发现可以直接贪心。
把住户按照推销疲劳从大到小排序,向X人推销的最大值,有两种可能。
第一种,向前X人推销。第二种,向前X-1人和a最大的人推销。当前X人包含A最大的时,就只有一种情况。
代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1000005;
struct node{
int a,b;
}x[maxn];
int cmp(node xx,node yy){
return xx.b>yy.b;
}
int sum[maxn],maxx[maxn];
int main()
{
int n,i;
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&x[i].a);
for(i=1;i<=n;i++)scanf("%d",&x[i].b);
sort(x+1,x+n+1,cmp);
//查找最大的a
int maxa=0,mark=0;
for(i=1;i<=n;i++){
if(x[i].a>maxa){
maxa=x[i].a;
mark=i;
}
}
int ans;
//预处理前缀和
for(i=1;i<=n;i++)sum[i]=sum[i-1]+x[i].b;
//预处理前i最大的a
for(i=1;i<=n;i++)maxx[i]=max(x[i].a,maxx[i-1]);
for(i=1;i<=n;i++){
if(mark>i){
ans=max(maxx[i]*2+sum[i],maxa*2+sum[i-1]+x[mark].b);
}
else ans=maxa*2+sum[i];
printf("%d\n",ans);
}
// cout << "Hello world!" << endl;
return 0;
}