洛谷 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的主要内容,如果未能解决你的问题,请参考以下文章