• 【Luogu 3195】玩具装箱


    【题目链接】传送门

    【写在前面】

    先写了个n^2的简单dp,这永远都是写题的第一步。

    状态开始会想到要设置成到第i个玩具分成了j批,但是并不知道分成多少批。

    直接将状态设置为分到第i个玩具的最小花费,这个类似任务安排里将三维的n^3变成一维的n^2。

    【code】

    #include<bits/stdc++.h>
    using namespace std;
    #define File "toy"
    #define ll long long
    #define ull unsigned long long
    inline void file(){
        freopen(File".in","r",stdin);
        freopen(File".out","w",stdout);
    }
    inline ll read(){
        ll x=0,f=1;   char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0'; ch=getchar();}
        return x*f;
    }
    const int mxn = 5e4+5;
    ll n,l;
    ll sc[mxn],f[mxn];
    int main(){
        file();
        n = read(),l = read();
        for(int i = 1;i <= n; ++i) sc[i] = sc[i-1]+read();
        memset(f,0x3f,sizeof f);
        f[0] = 0;
        for(int i = 1;i <= n; ++i)
            for(int j = 0;j < i; ++j)
                f[i] = min(f[i],f[j]+(i-j-1+sc[i]-sc[j]-l)*(i-j-1+sc[i]-sc[j]-l));
        printf("%lld
    ",f[n]);
        return 0;
    }
    /*
    5 4
    3
    4
    2
    1
    4
    */
    View Code

     以上为n^2的暴力,在luogu上20在校oj60。

    【题解大意】

    好的开始推斜率优化的式子。

    给我的启示就是,

    除了移项大法求斜率优化的式子,

    还可以有,

    假设两个决策是将当前 i 转移的决策点x,y的状态,

    不妨假设x,y大小值关系和dp值的大小关系,

    然后再大力移项,这样思路就会清晰很多。

    所谓的斜率优化其实就是找到单调性,

    只不过是两个值对应着坐标轴中相应的斜率。 

    【code】

    #include<bits/stdc++.h>
    using namespace std;
    #define File ""
    #define ll long long
    #define ull unsigned long long
    inline void file(){
        freopen(File".in","r",stdin);
        freopen(File".out","w",stdout);
    }
    inline ll read(){
        ll x=0,f=1;   char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0'; ch=getchar();}
        return x*f;
    }
    const int mxn = 5e4+5;
    ll n,L,s;
    int l,r;
    int q[mxn];
    ll f[mxn],dp[mxn],g[mxn];
    inline double slope(int y,int x) {
        return (double)(dp[x]+g[x]-(dp[y]+g[y]))/(f[x]-f[y]);
    }
    int main(){
    //    file();
        n = read(),L = read();
        for(int i = 1; i <= n; ++i) s+=read(),f[i]=s+i,g[i] = (f[i]+L+1)*(f[i]+L+1);
        g[0] = (L+1)*(L+1);
        for(int i = 1; i <= n; ++i){
            while(l<r && 2*f[i] >= slope(q[l],q[l+1])) l++;
            dp[i] = dp[q[l]] + (f[i]-f[q[l]]-1-L)*(f[i]-f[q[l]]-1-L);
            while(l<r && slope(q[r],i) < slope(q[r-1],q[r])) r--;
            q[++r] = i;
        }
    //    for(int i = 1;i <= n; ++i) printf("%d ",f[i]);
    //    puts("");
    //    for(int i = 1;i <= n; ++i) printf("%d ",g[i]);
    //    puts("");
        printf("%lld
    ",dp[n]);
        return 0;
    }
    /*
    5 4
    3
    4
    2
    1
    4
    */
    View Code
  • 相关阅读:
    华为牛人在华为工作十年的感悟!(有点长)(转载)
    C# 10进制与16进制相互转换
    Linux必学的60个命令
    项目管理
    网络数据加密需要解决三个问题:
    DES加密/解密的应用
    一个比较牛的加密算法
    开发完成后总结心得(团队会议稿) (转载)
    相当于序列化与反序列化,但是不用借助外部文件
    软件开发设计常识
  • 原文地址:https://www.cnblogs.com/ve-2021/p/10832804.html
Copyright © 2020-2023  润新知