Educational Codeforces Round 97 (Rated for Div. 2)

C. Chef Monocarp || dp

首先得到结论:先做好的菜应该先出(至少不慢:eg. 做好5 6 出菜1 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]转移过来的。然后取两种情况的最小值即可。

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

初始化问题:

对于不可能的情况: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;
}

 

上一篇:222. 完全二叉树的节点个数 (二叉树遍历)


下一篇:Numpy 怎么把arange ()产生的列表 变成一个行向量或者列向量