zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 97 (Rated for Div. 2)

    C. Chef Monocarp || dp

    1. 首先得到结论:先做好的菜应该先出(至少不慢:eg. 做好5 6 出菜1 2)

    那么先把菜按做好的时间排序。

    2. 定义dp[i][j]为:前i分钟做了j道菜,时间差的最小值。那这个状态是由什么转移过来的呢?考虑第i分钟是否做了第j道菜。如果做了,那么就说明前i-1分钟做了j-1道菜,那么就是由dp[i-1][j-1]转移过来的,差值为(a[i] - j)的绝对值;如果没做,那么就说明前i-1分钟做了j道菜,那么就是由dp[i-1][j]转移过来的。然后取两种情况的最小值即可。

    3. 注意,对于每一个i,遍历j的时候都不应该超过i,因为同一时间最多只能出一道菜,所以前i分钟最多做i道菜。

    4. i与j的遍历范围:i最大为300,j最大为n(且j不超过i)。

    5. 初始化问题:

    对于不可能的情况:eg. j > i,处理方法:if判断或者初始化为INF。

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5 + 4;
    
    int a[222], dp[306][222];
    
    int main()
    {
        int q;
        cin >> q;
        while(q--)
        {
            int n;
            cin >> n;
            for(int i = 1; i <= n; ++i)
                scanf("%d", &a[i]);
            sort(a + 1, a + 1 + n);
            //for(int j = 1; j <= 300; ++j) dp[0][j] = 333;
            for(int i = 1; i <= 300; ++i)
            {
                for(int j = 1; j <= i && j <= n; ++j)
                {
                    if(j == i) dp[i][j] = dp[i-1][j-1] + abs(a[j] - i);
                    else dp[i][j] = min(dp[i-1][j-1] + abs(a[j] - i), dp[i-1][j]);
                }
            }
            cout << dp[300][n] << endl;
        }
        return 0;
    }
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5 + 4;
    const int INF = 0x3f3f3f3f;
    int a[222], dp[306][222];
    
    int main()
    {
        int q;
        cin >> q;
        while(q--)
        {
            int n;
            cin >> n;
            for(int i = 1; i <= n; ++i)
                scanf("%d", &a[i]);
            sort(a + 1, a + 1 + n);
            for(int i = 0; i <= 300; ++i)
                for(int j = 0; j <= 200; ++j)
                    dp[i][j] = INF;
            dp[0][0] = 0;
            for(int i = 1; i <= 300; ++i)
            {
                dp[i][0] = 0;
                for(int j = 1; j <= i && j <= n; ++j)
                {
                    //if(j == i) dp[i][j] = dp[i-1][j-1] + abs(a[j] - i);
                    dp[i][j] = min(dp[i-1][j-1] + abs(a[j] - i), dp[i-1][j]);
                }
            }
            cout << dp[300][n] << endl;
        }
        return 0;
    }
  • 相关阅读:
    深入比特币原理(四)——锁定脚本(locking script)与解锁脚本(unlocking script)
    深入比特币原理(三)——交易的输入(input)与输出(output)
    深入比特币原理(二)——比特币密钥地址生成
    [JLOI2013]删除物品
    [POI2007]MEG-Megalopolis
    [HNOI2008]遥远的行星
    [JSOI2008]最大数maxnumber
    [HNOI2008]水平可见直线
    [JSOI2008]星球大战starwar
    [HNOI2008]越狱
  • 原文地址:https://www.cnblogs.com/Maxx-el/p/13908462.html
Copyright © 2011-2022 走看看