[BZOJ2131]免费的馅饼(DP+树状数组)
来源:互联网 发布:sql insert多条记录 编辑:程序博客网 时间:2024/05/29 11:48
=== ===
这里放传送门
=== ===
题解
这个题有点GG的一个地方就是能想出来的方法很多但是能优化到可做范围内的方法不多。。有一种方法是用f[i][j]表示这个人第i个时刻在第j个位置能够得到的最大价值,但这样转移已经是O(1)的了,没有办法再优化了。
然后又想到了一种做法就是先把馅饼按时间从小到大排序,用f[i]表示到第i个馅饼,第i个必须选的最大值,然后枚举[1..i-1]的所有j,如果它接到a[j]这个馅饼以后能在规定时间内跑到a[i],就用f[j]来更新f[i]。
一开始觉得这玩意儿可能可以用线段树查询一个区间最值啊之类的东西,但是后来发现这样递推的话对于决策j是有两个要求的,一个是时间t,一个是位置pos,并且这两个东西互相牵制,也就是可以作为决策点的j不是一个连续的区间,是断断续续的。这样的话就不大可以了。。。于是最后直接改了DP思路。。
考虑什么样的j能够作为决策点,就是说,对于当前的a[i]和想要用作决策的点a[j],它的时间限制是
那么如果j可以作为i的决策点就可以列出一个不等式。为了消掉难搞的绝对值我们分两种情况讨论。当i的pos大于j的pos的时候,就是
同样,当i的pos小于j的pos的时候,我们可以化出式子:
一开始想分别按照pos大或者pos小来做两遍,但是显然不行因为它可能来回跑。后来突然发现如果把那一大坨限制用
那么来证一下吧!首先用前面的来推出后面的。当i的pos大于j的pos并且i的w1大于j的w1的时候,把w1加上两倍的pos就变成了w2,这个时候相当于是大的那一边加上较大的数字,小的那一边加上较小的数字,大小关系不变;当i的pos小于j的pos的时候证明方法是类似的。用后面的式子推出前面的那就很显然了。。。(众:明明是懒得写吧!ATP:啦啦啦)
那么只需要把所有馅饼按照w1为第一关键字,w2为第二关键字排序,然后用树状数组维护前缀最大值就可以了。注意作为下标的w2要离散化。
代码
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int w,n,f[100010],hash[100010],cnt,ans,s[100010];struct pies{ int t,p,v,w1,w2;}a[100010];int comp(pies a,pies b){return a.w1<b.w1||a.w1==b.w1&&a.w2<=b.w2;}int lowbit(int x){return x&(-x);}int ask(int i){ int Max=0; while (i!=0){ Max=max(Max,s[i]); i-=lowbit(i); } return Max;}void add(int i,int val){ while (i<=cnt){ s[i]=max(s[i],val); i+=lowbit(i); }}int main(){ scanf("%d%d",&w,&n); for (int i=1;i<=n;i++){ scanf("%d%d%d",&a[i].t,&a[i].p,&a[i].v); a[i].t*=2; a[i].w1=a[i].t-a[i].p; a[i].w2=a[i].t+a[i].p; hash[++cnt]=a[i].w2; } sort(hash+1,hash+cnt+1); cnt=unique(hash+1,hash+cnt+1)-hash-1; for (int i=1;i<=n;i++) a[i].w2=lower_bound(hash+1,hash+cnt+1,a[i].w2)-hash; sort(a+1,a+n+1,comp); for (int i=1;i<=n;i++){ f[i]=ask(a[i].w2)+a[i].v; ans=max(ans,f[i]); add(a[i].w2,f[i]); } printf("%d\n",ans); return 0;}
偏偏在最后出现的补充说明
为啥我这题解写了这么长。。。。。。。。。。。。。
题解比代码写的长系列= =
- [BZOJ2131]免费的馅饼(DP+树状数组)
- [BZOJ2131]免费的馅饼-树状数组优化DP
- bzoj2131: 免费的馅饼
- [bzoj2131] 免费的馅饼
- 【BZOJ2131】免费的馅饼,坐标转换与DP
- bzoj 2131: 免费的馅饼(树状数组+DP)
- [BZOJ]2131: 免费的馅饼 DP+树状数组
- 免费馅饼(dp)
- 免费馅饼(dp)
- 免费馅饼 (dp)
- NYOJ613-免费馅饼(DP)
- hdu1176免费馅饼(dp)
- hdoj1176_免费馅饼(dp)
- hdu1176 免费馅饼(dp)
- hdoj1176 免费馅饼(DP)
- HDOJ1176. 免费馅饼.(DP)
- nyistOJ-免费馅饼(DP)
- DP+滚动数组-HDU-1176-免费馅饼
- HDU 3984 迷宫问题
- 输入年月日时分秒,输出该年月日时分秒的下一秒
- 【机器学习】使用python实现ANN
- 机器学习中关于正则项的一些摘抄
- 三角形面积=SQRT(S*(S-a)*(S-b)*(S-c)) 其中S=(a+b+c)/2,a、b、c为三角形的三边。 定义两个带参的宏,一个用来求area, 另一个宏用来求S。 写程序,在程序中用带
- [BZOJ2131]免费的馅饼(DP+树状数组)
- 以下设计模式中,哪一项不属于结构性模式
- Shell环境变量汇总
- HDU
- Flume-ng源码解析之Source组件
- ACM15题
- [2017-3-10]BNUZ套题比赛div2 C
- Longest Increasing Subsequence
- 深度学习(三):初级卷积神经网络