暴力dp,dp[i]
表示第i分钟的最大收益
那么枚举时间、上次从哪个工厂走来以及步数,直接dp:
d p [ i ] = max ( d p [ i ] , d p [ i − k ] + t o t p a t h v a l u e − c o s t [ s t a r t p o i n t ] ) dp[i] = \max(dp[i],dp[i-k]+totpathvalue-cost[startpoint]) dp[i]=max(dp[i],dp[i−k]+totpathvalue−cost[startpoint])
本来是 O ( n 3 ) O(n^3) O(n3)的,由于根本跑不满,可以轻松跑过去
Code:
#include
#include
#include
#include
#include
#include
#define MAXN 1050
#define INF 999999999
using namespace std;
int dp[MAXN], w[MAXN], v[MAXN][MAXN], n, m, pace;
inline int read () {
register int s = 0, w = 1;
register char ch = getchar ();
while (! isdigit (ch)) {if (ch == '-') w = -1; ch = getchar ();}
while (isdigit (ch)) {s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar ();}
return s * w;
}
int main () {
n = read (), m = read (), pace = read ();
for (register int i = 1; i <= n; i++)
for (register int j = 1; j <= m; j++)
v[i][j] = read ();
for (register int i = 1; i <= n; i++) w[i] = read ();
for (register int i = 0; i <= m + 2; i++) dp[i] = -INF;
dp[0] = 0;
for (register int i = 1; i <= m; i++)
for (register int j = 1; j <= n; j++) {
int cnt = 0;
for (register int k = 1; k <= min (i, pace); k++) {
int st = j - k > 0 ? j - k : n + j - k;
cnt += v[st][i - k + 1];
dp[i] = max (dp[i], dp[i - k] + cnt - w[st]);
}
}
return printf ("%d\n", dp[m]), 0;
}