You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

53 lines
3.1 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
/*
https://www.bilibili.com/video/BV1iT4y1U7tV/?spm_id_from=333.999.0.0
1
2
3,1n road-=n
4p
f[N]
5+
*/
int gold[N][N]; // gold[i][j]:第i条路第j个时刻可以获得的金币数量
int cost[N]; // cost[i]:在i个工厂购买机器人的花费
int n, m, p; // n个工厂,m个单位时间,p:机器人行走次数的上限
int f[N]; // f[i]:在前i个时间内可以获得的最多金币数量
int main() {
cin >> n >> m >> p; // 工厂数量,最长的时长,机器人可以行走的次数上限
for (int i = 1; i <= n; i++) // n个工厂比如2个工厂其实有两条路径 就是1->2,2->1,工厂数量也就是路径数量
for (int j = 1; j <= m; j++) // m个时长
cin >> gold[i][j]; // 每段路径,在每个单位时间,可以获取到的金币数量
for (int i = 1; i <= n; i++) cin >> cost[i]; // 在每个工厂购买机器人需要花费的金币数量
// !!!!!!注意!!!!!!
// 有效状态初始化为负无穷不能i=0开始因为下面的代码中会依赖i=0,i=0时f[i]=0
for (int i = 1; i <= m; i++) f[i] = -1e9;
for (int i = 1; i <= m; i++) { // 枚举每个单位时间
for (int j = 1; j <= n; j++) { // 枚举每个工厂
int tmp = f[i - 1] - cost[j]; // 上一个时间单元的最大值减去在j这个工厂购买机器人的花费金币数
for (int k = 0; k < p && i + k <= m; k++) {
int road = j + k; // 从j这个工厂开始走k步已减1是哪个道路,比如从1号工厂走0步就是1号道路
int time = i + k; // 到达了哪一时刻
if (road > n) road = road - n; // 环形
tmp += gold[road][time]; // 加上此道路,此时刻捡起来的金币数
f[time] = max(f[time], tmp); // 不断取最大值
}
}
}
// 输出
printf("%d\n", f[m]);
return 0;
}