洛谷 2672

Posted TSOI_Vergil

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 2672相关的知识,希望对你有一定的参考价值。

    首先我们考虑x=n的情况,这个答案是唯一确定的,那么当x=n-1时,我们就需要删去一家用户,那么我们要保证删掉后减少的疲劳值最小,对于最后一家用户,如果删掉它的话,减少的疲劳值就是pl[i]+(s[i]-s[pre[i]])*2,对于其他用户减少的疲劳值就是pl[i],那么我们考虑x=k是否一定是从x=k+1的最优解删除一家用户得来,如果x=k的最优解不是由x=k+1的最优解删除得到,那么在x=k的最优解中加入一家用户一定可以更新x=k+1的最优解。因此我们知道了x=k一定是由x=k+1删除一家用户得到,这样我们删除的用户一定是min(pl[i],pl[cur]+(s[cur]-s[pre[cur]])*2),其中cur是位置最靠后的用户,我们可以提前按pl[i]排序,然后用链表维护cur就可以。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 100005
int pre[maxn],next[maxn];
int n,s[maxn],cur,ans[maxn],p,temp,pl[maxn];
bool vis[maxn];
struct Vergil

	int key,id;	
t[maxn];

bool cmp(Vergil a,Vergil b) 

	return a.key<b.key;	


int main()

	scanf("%d",&n);
	for (int i=1;i<=n;i++) scanf("%d",s+i);
	for (int i=1;i<=n;i++) 
	
		t[i].id=i;
		scanf("%d",&pl[i]);
		t[i].key=pl[i];
		temp+=t[i].key;
	
	temp+=s[n]*2;
	ans[n]=temp;
	sort(t+1,t+n+1,cmp);
	for (int i=1;i<=n;i++) 
	
		pre[i]=i-1;
		next[i]=i+1;	
	
	next[n]=0;
	cur=n;p=1;
	for (int i=n-1;i>=1;i--) 
	
		while (cur==t[p].id||vis[t[p].id]) p++;
		if (t[p].key<=(s[cur]-s[pre[cur]])*2+pl[cur]) 
		
			temp-=t[p].key;
			int od=t[p].id;
			next[pre[od]]=next[od];
			pre[next[od]]=pre[od];
			p++;
		
		else 
		
			temp-=(s[cur]-s[pre[cur]])*2+pl[cur];
			vis[cur]=1;
			next[pre[cur]]=0;
			cur=pre[cur];
		
		ans[i]=temp;
		
	for (int i=1;i<=n;i++) printf("%d\\n",ans[i]);
	return 0;	


以上是关于洛谷 2672的主要内容,如果未能解决你的问题,请参考以下文章

luoguP2672 推销员

洛谷P2717 寒假作业

洛谷 P2717 寒假作业

洛谷P1102 A-B数对

洛谷——P1102 A-B数对

洛谷 P1102 A-B数对