第十二节 动态规划 - 4

A. 美食大赛

题目描述

美食城正在举行一年一度的美食大赛。小 \(Q\) 是其中一位参赛选手,他有 \(n\) 个食材,第 \(i\) 个食材做成菜所需要的时间为 \(c_i\)。由于新鲜度的问题,如果第 \(i\) 个食材在 \(t\) 时间时才被做成菜,那么这道菜的美味度为 \(a_i - t \times b_i\),其中 \(a_i\)\(b_i\) 是给定的参数。大赛时间紧张,总共只有 \(T\) 的时间。小 \(Q\) 想在 \(T\) 时间内做出的菜的美味度之和尽可能大,你能帮帮他吗?

输入格式

第一行包含两个整数 \(T\)\(n\)

接下来三行,每行 \(n\) 个数,分别表示 \(a_1 ~ a_n\)\(b_1 ~ b_n\)\(c_1 ~ c_n\)

输出格式

输出一行一个数,表示答案。

样例输入

74 1
502
2
47

样例输出

408

数据规模

\(1 \le n \le 50\),其余所有数都不超过 \(10^5\)

点击查看代码
#include<iostream>
#include<algorithm>
using namespace std;

struct node {
    long long a, b, c;
} p[55];
long long T, n, dp[100005];

bool cmp(node x, node y) {
    return x.c * y.b < y.c * x.b;
}

int main() {
    cin >> T >> n;
    for(int i = 1; i <= n; i ++) cin >> p[i].a;
    for(int i = 1; i <= n; i ++) cin >> p[i].b;
    for(int i = 1; i <= n; i ++) cin >> p[i].c;
    sort(p + 1, p + n + 1, cmp);
    for(int i = 1; i <= n; i ++) {
        for(int j = T; j >= p[i].c; j --) {
            dp[j] = max(dp[j], dp[j - p[i].c] + p[i].a - j * p[i].b);
        }
    }
    long long ans = 0;
    for(int i = 0; i <= T; i ++) ans = max(ans, dp[i]);
    cout << ans << endl;
    return 0;
}
编译结果
compiled successfully
time: 15ms, memory: 4192kb, score: 100, status: Accepted
> test 1: time: 0ms, memory: 3396kb, points: 10, status: Accepted
> test 2: time: 2ms, memory: 3916kb, points: 10, status: Accepted
> test 3: time: 4ms, memory: 4004kb, points: 10, status: Accepted
> test 4: time: 4ms, memory: 4192kb, points: 10, status: Accepted
> test 5: time: 0ms, memory: 3544kb, points: 10, status: Accepted
> test 6: time: 1ms, memory: 3508kb, points: 10, status: Accepted
> test 7: time: 1ms, memory: 3420kb, points: 10, status: Accepted
> test 8: time: 1ms, memory: 3440kb, points: 10, status: Accepted
> test 9: time: 1ms, memory: 3612kb, points: 10, status: Accepted
> test 10: time: 1ms, memory: 3368kb, points: 10, status: Accepted

B. 进程调度

题目描述:

某台计算机有两个 \(CPU\)。现在有 \(n\) 个进程需要执行,而进程只有 \(k\) 种(编号为 \(1 ~ k\))。

\(i\) 种进程在任意一个 \(CPU\) 上执行时,如果该 \(CPU\) 上执行的前一个进程也是第 \(i\) 种,则只需要花费 \(hot_i\) 时间;如果不是第 \(i\) 种,则需要花费 \(cold_i\) 时间。

现在你需要做进程调度,依次执行完 \(1 ~ n\) 的进程。

需要注意,必须当第 \(i\) 个进程执行完之后,你才能安排第 \(i + 1\) 个进程。请问执行完所有进程的最少时间是多少呢?

输入格式:

第一行包含一个整数 \(T\),表示数据组数。

每组数据第一行包括两个数 \(n\)\(k\),接下来一行 \(n\) 个整数,表示每个进程是哪一种进程,接下来一行 \(k\) 个整数,表示 \(cold_1 ∼ cold_k\),再接下来一行 \(k\) 个整数 \(hot_1 ∼ hot_k\)

输出格式:

输出 \(T\) 行,每行一个整数,表示答案。

样例输入:

9
3 2
1 2 2
3 2
2 1
4 2
1 2 1 2
5 3
2 1
4 3
1 2 3 1
100 100 100
1 1 1
5 2
2 1 2 1 1
65 45
54 7
5 3
1 3 2 1 2
2 2 2
1 1 1
5 1
1 1 1 1 1
1000000000
999999999
5 6
1 6 1 4 1
3 6 4 1 4 5
1 1 1 1 4 1
1 3
3
4 5 6
1 2 3
8 3
3 3 3 1 2 3 2 1
10 10 8
10 10 5

样例输出:

6
11
301
225
8
4999999996
11
6
63

数据规模:

\(1 \le t \le 10\)\(1 \le n,k \le 5000\)\(1 \le hot_i \le cold_i \le 10^9\)

点击查看代码
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;

#define int long long
int T, n, k, a[5005], h[5005], c[5005];
int dp[5005][5005];
int ans = 0;

signed main() {
    cin >> T;
    while(T --) {
        ans = 0x3f3f3f3f3f3f3f3f;
        memset(dp, 0x3f3f3f3f, sizeof dp);
        memset(h, 0, sizeof h);
        memset(c, 0, sizeof c);
        memset(a, 0, sizeof a);
        cin >> n >> k;
        for(int i = 1; i <= n; i ++) cin >> a[i];
        for(int i = 1; i <= k; i ++) cin >> c[i];
        for(int i = 1; i <= k; i ++) cin >> h[i];
        dp[1][0] = dp[0][1] = c[a[1]];
        for(int i = 2; i <= n; i ++) {
            for(int j = 0; j <= i - 2; j ++) {
                dp[i][i - 1] = min(dp[i][i - 1], dp[j][i - 1] + (a[i] == a[j] ? h[a[i]] : c[a[i]]));
                dp[i][j] = min(dp[i][j], dp[i - 1][j] + (a[i] == a[i - 1] ? h[a[i]] : c[a[i]]));
                dp[i - 1][i] = min(dp[i - 1][i], dp[i - 1][j] + (a[i] == a[j] ? h[a[i]] : c[a[i]]));
                dp[j][i] = min(dp[j][i], dp[j][i - 1] + (a[i] == a[i - 1] ? h[a[i]] : c[a[i]]));
            }
        }
        for(int i = 0; i < n; i ++)
            ans = min(ans, min(dp[n][i], dp[i][n]));
        cout << ans << endl;
    }
    return 0;
}
编译结果
compiled successfully
time: 7747ms, memory: 199288kb, score: 100, status: Accepted
> test 1: time: 872ms, memory: 199188kb, points: 10, status: Accepted
> test 2: time: 515ms, memory: 199036kb, points: 10, status: Accepted
> test 3: time: 833ms, memory: 199180kb, points: 10, status: Accepted
> test 4: time: 657ms, memory: 199256kb, points: 10, status: Accepted
> test 5: time: 843ms, memory: 199176kb, points: 10, status: Accepted
> test 6: time: 766ms, memory: 199268kb, points: 10, status: Accepted
> test 7: time: 645ms, memory: 199040kb, points: 10, status: Accepted
> test 8: time: 950ms, memory: 199252kb, points: 10, status: Accepted
> test 9: time: 828ms, memory: 199268kb, points: 10, status: Accepted
> test 10: time: 838ms, memory: 199288kb, points: 10, status: Accepted
posted @ 2023-07-24 08:49  So_noSlack  阅读(145)  评论(0编辑  收藏  举报