1 条题解
-
0
本题要求根据不同客户租船天数及各选择的截止日期和金额,按客户请求顺序处理租船事宜,计算出最大利润。
数据存储:用day[i]记录第i个客户想租船的天数;num[i][j]表示第i个客户在截止日期为j时能获得的最大金额;dp[j]表示在截止日期为j时能获得的最大利润。 状态转移: 遍历每个客户的选择,对于每个选择(a, b, c)(客户a,截止日期b,金额c),从截止日期b开始逆序遍历到day[a],更新num[a][j]为当前能获得的最大金额。逆序更新是因为要保证在同一截止日期下,不会重复计算同一个客户的租船收益。 遍历每个客户i,再从100逆序遍历到day[i],进行状态转移dp[j] = max(dp[j], dp[j - day[i]] + num[i][j]) 。这表示在截止日期j时,要么不选择该客户(保持dp[j]不变),要么选择该客户(在之前截止日期j - day[i]的最大利润基础上加上当前客户在截止日期j时能获得的最大金额)。 结果获取:最后遍历dp数组,找出其中的最大值,即为能获得的最大利润。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int dp[110]; int num[110][110], day[110]; int main() { int t = 0, n, m, i, j, a, b, c, ans; while (~scanf("%d", &n)) { for (i = 1; i <= n; i++) scanf("%d", &day[i]); scanf("%d", &m); memset(dp, 0, sizeof(dp)); memset(num, 0, sizeof(num)); while (m--) { scanf("%d%d%d", &a, &b, &c); //客户 截止日期 获益 for (j = b; j >= day[a]; j--) //在截止日期时收回,记得这里是逆序更新! { num[a][j] = max(num[a][j], c); //printf("num[%d][%d] : %d\n", a, j, num[a][j]); } } for (i = 1; i <= n; i++) for (j = 100; j >= day[i]; j--) { dp[j] = max(dp[j], dp[j - day[i]] + num[i][j]); //printf("dp[%d] : %d\n", j, dp[j]); } ans = 0; for (i = 0; i <= 100; i++) ans = max(ans, dp[i]); if (t != 0) printf("\n"); t++; printf("%d\n", ans); } }
- 1
信息
- ID
- 279
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 8
- 已通过
- 1
- 上传者