Codeforces 358D DP
题意:有n只兔子需要喂养,每只兔子被喂养后的幸福感取决于与它相邻的兔子中已经被喂养的数量。现在问喂养这n只兔子可以获得的总幸福感最多是多少?
思路:初步分析题目发现,一只兔子被喂养获得的幸福感取决于其它兔子的喂养情况,所有首先想到状压DP。但是n到3000, 所以不行。我们发现兔子获得的幸福感只取决于与它相邻的兔子的幸福感。更准确的说,取决于与它相邻的兔子和它自己被喂养的先后顺序,所以,我们只要表示出与它相邻的兔子和它的喂养先后顺序就解决问题了。设dp[i][0]为已经喂养的前i只兔子,并且第i只兔子比第i + 1只兔子先喂养。dp[i][1]是后喂养,因为我们枚举i状态来更新i + 1状态。因为我们知道了喂养顺序,所以就知道了第i只兔子获得的幸福感。
代码:
#include <bits/stdc++.h> #define LL long long #define INF 0x3f3f3f3f #define pii pair<int, int> #define db double using namespace std; const int maxn = 3010; int val[3][maxn], f[maxn][2]; int main() { int n; scanf("%d", &n); for (int j = 0; j < 3; j++) { for (int i = 1; i <= n; i++) { scanf("%d", &val[j][i]); } } f[1][0] = val[0][1]; f[1][1] = val[1][1]; for (int i = 1; i < n - 1; i++) { f[i + 1][0] = max(f[i][0] + val[1][i + 1], f[i][1] + val[0][i + 1]); f[i + 1][1] = max(f[i][0] + val[2][i + 1], f[i][1] + val[1][i + 1]); } if(n > 1) f[n][0] = max(f[n - 1][0] + val[1][n], f[n - 1][1] + val[0][n]); // f[n][1] = max(f[n - 1][0] + val[1][n], f[n - 1][1] + val[0][n]); printf("%d\n", f[n][0]); }