BZOJ3156 防御准备

mac2022-06-30  120

目录

BZOJ3156 防御准备题解code

BZOJ3156 防御准备

题目传送门

题解

这道\(Dp\)题目也算是比较清真了吧,看到数据范围其实就差不多可以知道是个斜率优化\(Dp\)了。我们比较容易地可以写出转移方程:\(dp[i]=max(dp[j]+\sum_{k=j+1}^{i-1}(i-k))+a[i] \Rightarrow dp[i]=max(dp[j]+\sum_{k=j+1}^{i-1}i-\sum_{k=j+1}^{i-1}k)+a[i])\) \(\Rightarrow dp[i]=max(dp[j]+(i-j-1)*i+\frac{(j+i)*(i-j-1)}{2})\)。然后还是像斜率优化\(Dp\)一样,我们列出不等式:

\(dp[j]+(i-j-1)*i+\frac{(j+i)*(i-j-1)}{2}\geq dp[k]+(i-k-1)*i+\frac{(k+i)*(i-k-1)}{2}\)\(j<k\)并且 \(k\)\(j\)要优)

然后整理一下可以得到:

\(\frac{f[k]-f[j]+k^2-j^2+k-j}{2*(k-j)}\leq i\)

之后的事情就十分简单了,套用斜率优化的板子就行了。 话说看了黄学长的博客发现还有把\(a[i]\)反过来读入的方法。。表示有点不理解这个方法啊。。

code

#include <bits/stdc++.h> using namespace std; typedef long long ll; bool Finish_read; template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;} template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x+'0');} template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');} template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);} /*================Header Template==============*/ const int maxn=1e6+500; int n; ll a[maxn],f[maxn]; ll que[maxn],l,r; /*==================Define Area================*/ double Cal(ll j,ll k) { return (double)(2*(f[k]-f[j])+k*k-j*j+k-j)/(k-j); } int main() { read(n); for(int i=1;i<=n;i++) { read(a[i]); } for(int i=1;i<=n;i++) { while(l<r&&Cal(que[l],que[l+1])<2*i) l++; int t=que[l]; f[i]=f[t]+(i-t)*(i-t-1)/2+a[i]; while(l<r&&Cal(que[r-1],que[r])>Cal(que[r],i)) r--; que[++r]=i; } printf("%lld\n",f[n]); return 0; }

转载于:https://www.cnblogs.com/Apocrypha/p/9452891.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)