题解:P2672

题面

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}$$

子任务

  1. 暴力选取,复杂度 \(O(n\times 2^n)\).
  2. 定义深搜 \(\text{dfs}(m,p,s,l)\) 表示选了 \(m\) 户,上一户选的是第 \(p\) 户,累计口头推销带来的疲惫值 \(s\) ,走的最远距离 \(l\).

分析复杂度:对每个 \(X\) 而言, \(p\) 遍历,复杂度 \(O(n^2)\).

正解

由式子中 \(max\) 受到启发,左项只受距离最大值影响,那么讨论是否取距离最大值:

  1. 若取距离最大值,那么剩下 \(X-1\) 项取 \(\sum{c_j}\) 最大.
  2. 若不取最大值,那么所有 \(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;
}
posted @ 2025-08-20 20:55  badn  阅读(3)  评论(0)    收藏  举报