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
  • 相关阅读:
    AtCoder Regular Contest 093
    AtCoder Regular Contest 094
    G. Gangsters in Central City
    HGOI 20190711 题解
    HGOI20190710 题解
    HGOI 20190709 题解
    HGOI 20190708 题解
    HGOI20190707 题解
    HGOI20190706 题解
    HGOI 20190705 题解
  • 原文地址:https://www.cnblogs.com/mczhuang/p/7735447.html
Copyright © 2011-2022 走看看