一开始看到题目以为是最大能量项链一样的动规问题,但按照那种划分的话情况非常混乱,而且时间复杂度很大,所以行不通
因为某只hare的joy只有周围两只是否feed相关,所以可把n只hare的最大值分解为前n-1只1)在第n只之后feed的最大值 2)在第n只之前feed的最大值 再加上第n只对应的值。 因为前n-2只与第n只毫无关系,所以可以当做把他们先喂完。 然后再以此往前类推即可。 然后将递归转化为从头开始递推就可以了,,所以只要求出在第k项在第k+1项后feed时前面k项的最大值以及第k项在第k+1项之前feed时的最大值即可。
状态转移方程为 :
dp[i][0] = max(dp[i-1][1]+c[i], dp[i-1][0]+b[i]);
dp[i][1] = max(dp[i-1][1]+b[i], dp[i-1][0]+a[i]);
只需求到第n-1项,即可求出最大值 M = max(dp[i-1][0]+a[i], dp[i-1][1]+b[i]);
PS.要将n=1的情况单独考虑~
代码如下:
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int maxn = 3010; int a[maxn], b[maxn], c[maxn]; long long dp[maxn][2]; int main() { int n, i, j; long long M; scanf("%d", &n); for (i = 0; i < n; i++) scanf("%d", &a[i]); for (i = 0; i < n; i++) scanf("%d", &b[i]); for (i = 0; i < n; i++) scanf("%d", &c[i]); if (n == 1) M = a[0]; else { dp[0][0] = b[0]; dp[0][1] = a[0]; for (i = 1; i < n-1; i++) { dp[i][0] = max(dp[i-1][1]+c[i], dp[i-1][0]+b[i]); dp[i][1] = max(dp[i-1][1]+b[i], dp[i-1][0]+a[i]); } M = max(dp[i-1][0]+a[i], dp[i-1][1]+b[i]); } cout << M << endl; return 0; }