• CF1437C


    Solution:

    看到这道题很显然可以想到贪心是假算法,所以我们需要考虑如何使用 (dp) 。因为本题需要的是关于时间的,并且要取出物品,所以我们可以设计 (dp) 状态为 (f[i][j]) 表示在 (i) 时刻,取了前 (j) 个物品。一共有三种转移状态:

    (f[i][j]=minegin{cases}f[i][j]\f[i-1][j]\f[i-1][j-1]+abs(i-t[j])end{cases})

    (f[i-1][j]) 表示在 (i) 时刻不选第 (j) 个物品。(f[i-1][j-1]+abs(i-t[j])) 表示在第 (i) 个时刻取第 (j) 个物品的花费。

    但是你如果 (iin[1,n]) 那就会发现第二个样例就跑不过去了,这是因为你不光可以在 ([1,n]) 中,也可以在更后的时间里,也就是说你的 (iin[1,2n]) 才可以。当然最后输出的时候答案应该是:

    (ans=min(f[i][n]);iin[n,2n])

    最后输出 (ans) 即可得出正确答案。

    Code:

    #include<bits/stdc++.h>
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(c<'0' || c>'9'){if(c=='-') f=0;c=getchar();}
        while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
        return f?x:-x;
    }
    int T,n,t[210],f[410][210],ans;
    signed main()
    {
        T=read();
        while(T--)
        {
            n=read();
            for(int i=1;i<=n;i++) t[i]=read();
            sort(t+1,t+n+1);
            memset(f,0x3f,sizeof(f));
            f[0][0]=0;
            for(int i=1;i<=2*n;i++)
            {
                f[i][0]=0;
                for(int j=1;j<=min(i,n);j++)
                {
                    f[i][j]=min(f[i][j],f[i-1][j]);
                    f[i][j]=min(f[i][j],f[i-1][j-1]+abs(i-t[j]));
                }
            }
            ans=INT_MAX;
            for(int i=n;i<=2*n;i++) ans=min(ans,f[i][n]);
            printf("%d
    ",ans);
        }
        return 0;
    }
    
    
  • 相关阅读:
    此网页的安全性验证无效并且可能损坏的错误的解决方法
    fixSidebar简介与修正log
    Git可视化极简易教程 —— Git GUI使用方法
    windows平台快速搭建Linux(CentOS)
    CentOS在线安装Mysql5.7
    springboot集成mybatis(二)
    springboot测试、打包、部署
    springboot快速入门
    springboot集成mybatis(一)
    CentOS在线安装JDK
  • 原文地址:https://www.cnblogs.com/ForeverOIer/p/14169994.html
Copyright © 2020-2023  润新知