【NOIP2015】推销员
2016-11-03 20:26
357 查看
推(chuan)销员
分析
这里主要阐述一下我的分析思路。看起来挺直观的。
最初的想法,我们枚举每一个最远点mxp的位置,然后对之前的a进行排序。
那么以mxp为最远点,选x个的最大疲劳值为:
2∗s[mxp]+a[mxp]+(之前的前x−1大的a值的和)
这样的复杂度为O(n2logn),考试时就这样拿了个60pt。
但是,我们要尝试发现这道题的特性,来进行时间上的优化。
根据极大化思想,我们要尽可能排除不影响答案的(mxp,x)。
当x一定时,设i<j,i没有j优,这等价于:
2∗s[i]+a[i]+(i之前的前x−1大的a值的和)<2∗s[j]+a[j]+(j之前的前x−1大的a值的和)
记w[i]=2∗s[i]+a[i]
∴w[i]−w[j]<(j之前的前x−1大的a值的和)−(i之前的前x−1大的a值的和)
当x增大的时候,例如x变大到x+1,发现(j之前的前x大的a值的和)−(i之前的前x大的a值的和)的值一定是递增的,因为j之前的前x大的a值的和一定是j之前的前x−−1大的a值的和多一个数,i也一样,而i能选择到的j也能选择得到。
所以我们得到了决策单调性:对于x,i<j,i没有j优,那么随着x的增大,i仍然没有j优,所以对于x的询问的决策点会非严格单调递增。
接下来,很容易想到用单调队列什么的进行维护。
但怎么尝试都觉得不行……
这时候就一定要跳出来啦。
根据决策单调性这个重要的特点,考虑换一种思考的角度。
假如当前x−1这个询问我们决策点为cur,答案为res,现在要求x这个询问的决策点和答案。
我们有两种方法:
①在cur之前选择一个没有选择过的点i,Δ=a[i]
②在cur之后选择一个决策点,Δ=2∗s[i]+a[i]−2∗s[cur]
用两个堆实现即可。
有点意思。
代码
#include <cstdio> #include <cctype> #include <queue> using namespace std; #define rep(i,a,b) for (int i=(a);i<=(b);i++) #define x first #define y second #define mp make_pair typedef pair<int,int> PII; const int N=131072; int n; int s ,a ; int cur,vis ; priority_queue<PII> qs,qb; int res; inline int rd(void) { int x=0,f=1; char c=getchar(); for (;!isdigit(c);c=getchar()) if (c=='-') f=-1; for (;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } int main(void) { // freopen("a.in","r",stdin); // freopen("a.out","w",stdout); n=rd(); rep(i,1,n) s[i]=rd(); rep(i,1,n) a[i]=rd(); rep(i,1,n) qb.push(mp(2*s[i]+a[i],i)); PII t1,t2; int e1,e2,cs; rep(i,1,n) { while (!qs.empty()) { t1=qs.top(); if (vis[t1.y]) qs.pop(); else break; } while (!qb.empty()) { t2=qb.top(); if (t2.y<cur||vis[t2.y]) qb.pop(); else break; } e1=(!qs.empty()); e2=(!qb.empty()); if (!e1&&e2) cs=2; else if (e1&&!e2) cs=1; else if (e1&&e2) { t1=qs.top(),t2=qb.top(); if (t2.x-2*s[cur]>=t1.x) cs=2; else cs=1; } if (cs==1) { t1=qs.top(); qs.pop(); vis[t1.y]=1; res+=t1.x; } else if (cs==2) { t2=qb.top(); qb.pop(); vis[t2.y]=1; rep(j,cur+1,t2.y) if (!vis[j]) qs.push(mp(a[j],j)); res+=(t2.x-2*s[cur]); cur=t2.y; } printf("%d\n",res); } return 0; }
相关文章推荐
- [NOIp2015普及组]推销员
- 【NOIP2015普及组T4】推销员-优先队列
- Noip2015 普及组 推销员 题解
- NOIP2015 推销员
- |洛谷|NOIP2015|堆|P2672 推销员
- 【codevs 5126】[NOIP2015 普及组T4]推销员(贪心)
- NOIp2015P 推销员
- noip 2015 普及 第四题 推销员 stl之priority_queue
- code vs 5126 推销员 NOIP2015 (线段树+贪心)
- NOIP2015普及组 —— 推销员(salesman)
- [普及]NOIP 2015 推销员
- [NOIP2015][Vijos1977]推销员(heap)
- NOIP 2015 推销员
- [NOIP2015]推销员
- luogu2672推销员-贪心-(noip2015普及t4)
- 【NOIP2015普及组】 推销员(纪中数据-标准)
- 【NOIP2015模拟11.2晚】Lala买面包
- 【NOIP2015模拟11.2】有趣的有趣的家庭菜园
- JZOJ 4295【NOIP2015模拟11.2】愉快的logo设计
- UOJ 150 [NOIP2015]运输计划