题解:P2672
题面
![[../../题面/洛谷题面/P2672|P2672]]
分析
给定了 \(n\) 对 \((c_i,x_i)\)
要求对于 \(\forall X \in [1,n]\) ,选定 \(X\) 个数对 \(p_j\)( \(j\in [1,X]\) ),最大化每个 $$ans_X=2(\max{x_j})+\sum{c_j}$$
子任务
- 暴力选取,复杂度 \(O(n\times 2^n)\).
- 定义深搜 \(\text{dfs}(m,p,s,l)\) 表示选了 \(m\) 户,上一户选的是第 \(p\) 户,累计口头推销带来的疲惫值 \(s\) ,走的最远距离 \(l\).
分析复杂度:对每个 \(X\) 而言, \(p\) 遍历,复杂度 \(O(n^2)\).
正解
由式子中 \(max\) 受到启发,左项只受距离最大值影响,那么讨论是否取距离最大值:
- 若取距离最大值,那么剩下 \(X-1\) 项取 \(\sum{c_j}\) 最大.
- 若不取最大值,那么所有 \(X\) 项取 \(\sum{c_j}\) 最大
复杂度 \(O(n)\)
实现
结构体绑定数对 \(p_i=(c_i,x_i)\),从小到大排序 \(p_i\),则记
\(sum_i\) 为 \(x_i\) 前缀和
\(dist_i\) 为前 \(i\) 项最大 \(\ 2x_i\)
\(h_i\) 后 \(n-i+1\) 项最大 \(\ c_i+2x_i\)
\[ans_X=max(sum_i+dist_i,sum_{i-1}+h_i)
\]
代码
#include<bits/stdc++.h>
#define to(x,y); for(int x=1;x<=y;x++)
#define fr(x,y); for(int x=0;x<y;x++)
using namespace std;
typedef unsigned long long ull;
const int N=1e5+10;
int n,ans;
int sum[N],dist[N],h[N];
struct nd {int s,t;} p[N];
bool cmp(nd a,nd b){
if(a.t==b.t)return a.s>b.s;
return a.t>b.t;
}
int main(){
cin>>n;
to(i,n)scanf("%d",&p[i].s);
to(i,n)scanf("%d",&p[i].t);
sort(p+1,p+1+n,cmp);
to(i,n)sum[i]=sum[i-1]+p[i].t,dist[i]=max(dist[i-1],p[i].s*2);
h[n]=p[n].s*2+p[n].t;
for(int i=n-1;i>=1;i--)h[i]=max(h[i+1],p[i].s*2+p[i].t);
for(int i=1;i<=n;i++)printf("%d\n",max(sum[i]+dist[i],sum[i-1]+h[i]));
return 0;
}

浙公网安备 33010602011771号