zoukankan      html  css  js  c++  java
  • BZOJ 1597: [Usaco2008 Mar]土地购买

    做法:斜率优化DP

    斜率优化DP:Link

    预处理:sort处理可合并土地,得到a[]严格上升,b[]严格下降的序列

    朴素DP方程:F[i]=min f[j]+a[i]*b[j+1](0<j<i)

     朴素DP Code:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define ll long long 
     5 using namespace std;
     6 inline int read()
     7 {
     8     register int f=1,k=0;register char c=getchar();
     9     while (c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    10     while (c>='0'&&c<='9')k=k*10+c-'0',c=getchar();
    11     return k*f;
    12 }
    13 const int maxn=50100;
    14 struct qaq{
    15     ll a,b;
    16 }x[maxn],y[maxn];
    17 ll f[maxn];
    18 inline bool cmp(const qaq&a,const qaq&b){return a.a<b.a||(a.a==b.a&&a.b<b.b);}
    19 int main()
    20 {
    21     memset(f,0x7f,sizeof(f));
    22     register int i,n=read(),cur=1;
    23     for (i=1;i<=n;i++)
    24     x[i].a=read(),x[i].b=read();
    25     sort(x+1,x+1+n,cmp);
    26     y[1]=x[1];
    27     for (register int i=2;i<=n;i++)
    28     {
    29         while (x[i].b>=y[cur].b&&cur>0)cur--; 
    30         y[++cur]=x[i];
    31     }
    32     f[1]=y[1].a*y[1].b;
    33     for (register int i=1;i<=cur;i++)
    34     for (register int j=1;j<i;j++)
    35     f[i]=min(f[i],f[j]+y[i].a*y[j+1].b);
    36     printf("%lld
    ",f[cur]);
    37 }
    View Code

     斜率优化DP:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define ll long long 
    using namespace std;
    inline int read()
    {
        register int f=1,k=0;register char c=getchar();
        while (c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
        while (c>='0'&&c<='9')k=k*10+c-'0',c=getchar();
        return k*f;
    }
    const int maxn=50100;
    struct qaq{ll a,b;}x[maxn],y[maxn];
    ll f[maxn],q[maxn];
    inline int d(int a,int b){return (f[a]-f[b])/(y[b+1].b-y[a+1].b);}
    inline bool cmp(const qaq&a,const qaq&b){return a.a<b.a||(a.a==b.a&&a.b<b.b);}
    int main()
    {
        register int i,n=read(),cur=1,head=0,tail=1;
        for (i=1;i<=n;i++)x[i].a=read(),x[i].b=read();
        sort(x+1,x+1+n,cmp);
        y[1]=x[1];
        for (register int i=2;i<=n;y[++cur]=x[i++])while (x[i].b>=y[cur].b&&cur>0)cur--;
        for (register int i=1;i<=cur;i++)
        {
            while (tail-head>1&&d(q[head],q[head+1])<y[i].a)head++;
            f[i]=f[q[head]]+1ll*y[i].a*y[q[head]+1].b;
            while (tail-head>1&&d(q[tail-1],q[tail-2])>d(q[tail-1],i))tail--;
            q[tail++]=i;
        }
        printf("%lld
    ",f[cur]); 
    }
    View Code
  • 相关阅读:
    并发编程(六)并发队列
    并发编程(五)原子类
    Java基础一篇过(九)面向对象之多态【向上转型与向下转型】
    ArrayList源码解析
    Redis5设计与源码分析读后感(四)压缩列表
    Redis5设计与源码分析读后感(三)跳跃表
    Python学习————CBV模型
    Python学习————Django
    Python学习————JS
    Python学习————SEO和SEC
  • 原文地址:https://www.cnblogs.com/mczhuang/p/7735447.html
Copyright © 2011-2022 走看看