P1133 教主的花园
链接
https://www.luogu.com.cn/problem/P1133
思路
动态规划,我开始想的差不多,首先想到使用dp[i][j]表示前i个树,在第i号位种下了j树的最大收益。这里得考虑到都比两边高/低,所以想到加一个二维1/0。
递推:dp[i][j][0] = dp[i-1][k][1] + val[i][j]
这样。然后递推k就行。关键一个点就是由于dp会忘记第一棵树是多少,所以使用for遍历第一棵树。并且做好标记(这里初始化不要用for,见代码)
代码
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
const int N = 1e5 + 10;
int n;
int val[N][4];
int dp[N][4][2];
void solve()
{
cin >> n;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= 3; j++)
cin >> val[i][j];
int ans = 0;
for (int ix = 1; ix <= 3; ix++)
{
int begin = ix;
memset(dp, 0, sizeof(dp));
dp[1][ix][0] = dp[1][ix][1] = val[1][ix];//初始化只用把对应的ix初始化就行了
for (int i = 2; i <= n; i++)
{
dp[i][1][0] = max(dp[i - 1][2][1], dp[i - 1][3][1]) + val[i][1];
dp[i][2][0] = dp[i - 1][3][1] + val[i][2];
dp[i][2][1] = dp[i - 1][1][0] + val[i][2];
dp[i][3][1] = max(dp[i - 1][1][0], dp[i - 1][2][0]) + val[i][3];
}
if (begin == 1)
{
ans = max(ans, max(dp[n][2][1], dp[n][3][1]));
}
else if (begin == 2)
ans = max(ans, max(dp[n][1][0], dp[n][3][1]));
else ans = max(ans, max(dp[n][1][0], dp[n][2][0]));
}
cout << ans;
}
signed main()
{
IOS;
solve();
return 0;
}

浙公网安备 33010602011771号