首页 > 试题广场 >

漫展打卡奖励

[编程题]漫展打卡奖励
  • 热度指数:681 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解

某次漫展,已知有n个打卡点,每个打卡点的活动需要 m_i 分钟完成,完成后获得奖励点 r_i,已经打卡过的点不能再去。

需要在规定 m 分钟内完成,尽可能多的收获奖励点,求获得最多的奖励点数。


输入描述:

第一行两个整数,打卡点的数量 n 和限制时间 m

第 2 到 1 + n 行,每行两个整数 m_i,r_i

数字以空格分割,其中 0 < n <= 100,1 <= m <= 120,1 <= m_i <= 10,1 <= r_i <= 100



输出描述:
整数, 最大的奖励点数
示例1

输入

4 6
2 4
2 35
1 43
2 10

输出

88
01背包问题的模板,dp[i][j]表示在剩余时间为j分钟的情况下,考虑漫展0~i的最大奖励点,那么它有两种情况进行状态转移。
(1) 如果已经不够时间去漫展i进行打卡,则有dp[i][j] = dp[i-1][j],这个展不去了。
(2) 否则可以选择去与不去,如果去则应该加上这个展的奖励点,dp[i][j] = dp[i - 1][j-mi]+ri,否则与情况(1)相同,应该选择这两种策略中能让奖励点更多的策略:
            dp[i][j] = max(dp[i-1][j], dp[i - 1][j-mi]+ri)
n, m = map(int, input().strip().split())
ms, rs = [], []
for _ in range(n):
    mi, ri = map(int, input().strip().split())
    ms.append(mi)
    rs.append(ri)
maxScore = 0
dp = [[0]*(m + 1) for _ in range(n)]
for i in range(n):
    for j in range(m + 1):
        if j >= ms[i]:
            dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - ms[i]] + rs[i])     # 能看的情况下,选择看与不看中收益大的策略
        else:
            dp[i][j] = dp[i - 1][j]      # 时间受限,第i个展看不了
print(dp[-1][-1])

编辑于 2021-04-11 19:35:15 回复(0)
# include <stdio.h>
int dp[105][125];
int my_max(int x, int y)
{
    if(x >= y)
        return x;
    else
        return y;
}
int fun(int t[], int r[], int n, int m)
{
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            if(t[i] > j)
                dp[i][j] = dp[i-1][j];
            else 
                dp[i][j] = my_max(dp[i-1][j], dp[i-1][j - t[i]] + r[i]);
        }
    }
    return dp[n][m];
}
int main()
{
    int n, m;
    int t[105];
    int r[105];
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d %d", &t[i], &r[i]);
    }
    int res = fun(t, r, n, m);
    printf("%d", res);
    return 0;
}

发表于 2021-10-12 20:12:42 回复(0)
01 背包问题
import sys
n, m = map(int, sys.stdin.readline().strip().split(" "))
points = []
for i in range(n):
    m_i, r_i = map(int, sys.stdin.readline().strip().split(" "))
    points.append([m_i, r_i])
#print(points)    
# dp[i][j]: 当前已考虑i之前的所有点,剩余时间为j时的得分
dp = [[0]*(m+1) for _ in range(n+1)]
for i in range(1, n+1):
    for j in range(1, m+1):
        # 剩余时间不足
        m_i, r_i = points[i-1][0], points[i-1][1]
        if j < m_i:
            dp[i][j] = dp[i-1][j]
        else:
            dp[i][j] = max(dp[i-1][j], dp[i-1][j - m_i] + r_i)
print(dp[n][m])


发表于 2021-04-10 14:08:45 回复(0)