洛谷3195(HNOI2008)玩具装箱
生活随笔
收集整理的這篇文章主要介紹了
洛谷3195(HNOI2008)玩具装箱
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目:https://www.luogu.org/problemnew/show/P3195
自己做斜率優化的第一道題。
推成斜率優化的樣子很重要。
斜率優化的樣子就是從 j 中求 i 的話,關系式里一個量只和 i 有關,一個量只和 j 有關,一個量同時和 i 與 j 有關。
這時可以把那個 同時和 i 與 j 有關的量 里的和 j 有關的量看成 x[ j ],把只和 j 有關的量看成 y[ j ],然后只和 i 有關的量就是截距、x[ j ]前面的就是式子里的斜率。
(為了推出這樣的式子,可以設a,b等等,幫助自己推。大體思路是將與 i 或 j 或 i 和 j 有關的東西看成一個整體)
推出式子以后,找合適的 j 就是 j - 1 與 j 的斜率比式子里的斜率大(或小),而 j 與 j + 1 的斜率比式子里的斜率小(或大)的那個 j 。
找到 j 以后把式子變變形就得到推出dp[ i ] 的式子了。
可用單調隊列。
把a什么的寫成函數很方便。
#include<iostream> #include<cstdio> #include<cstring> #define ll long long #define db double using namespace std; const int N=50005; int n,L,h=1,t=1,q[N]; ll s[N],dp[N]; db a(int i){return s[i]+i;} db b(int i){return s[i]+i+L+1;} db x(int i){return b(i);} db y(int i){return b(i)*b(i)+dp[i];} db slope(int j,int i){return (y(i)-y(j))/(x(i)-x(j));} int main() {scanf("%d%d",&n,&L);ll z;for(int i=1;i<=n;i++){scanf("%lld",&z);s[i]=s[i-1]+z;}for(int i=1;i<=n;i++){while(h<t&&slope(q[h],q[h+1])<2*a(i))h++;dp[i]=(a(i)-b(q[h]))*(a(i)-b(q[h]))+dp[q[h]];while(t>h&&slope(q[t-1],q[t])>slope(q[t-1],i))t--;q[++t]=i;}printf("%lld",dp[n]);return 0; }?
轉載于:https://www.cnblogs.com/Narh/p/9139814.html
總結
以上是生活随笔為你收集整理的洛谷3195(HNOI2008)玩具装箱的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jquery知识巩固
- 下一篇: 树链剖分 完美的想法