[NOIpPJ2009]道路游戏——[简单DP]

[NOIpPJ2009]道路游戏——[简单DP]_第1张图片
[NOIpPJ2009]道路游戏——[简单DP]_第2张图片
【题意分析】

暴力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[ik]+totpathvaluecost[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;
}

你可能感兴趣的:(动态规划)