令dp[i][j]为i时刻j位置时的最大馅饼量。由于每个状态只能由临近的3个状态转移而来,所以可以较为简单的确定递推式。
第一个要思考的点:正推还是逆推?逆推的好,正推的话不知哪些状态可走,而逆推的话,是在当前状态下确定之前的状态,所以不存在这个问题。
第二个思考的点:为什么答案是dp[0][6],6是因为为了去掉越界的判断,把位置从[0,10]映射到了[1,11],0是因为,1时刻可能在4、5、6的位置,所以dp[1][6]并不能代表0时刻5开始的答案,上拔一层即可。
#include <iostream> #include <bits/stdc++.h> using namespace std; #define ll long long #define mst(a,b) memset(a,b,sizeof(a)) #define rep(i,a,b) for(ll i=(a);i<(b);++i) const int inf = 0x3f3f3f3f, maxN = 1e5 + 5; int dp[maxN][20]; #define max3(a,b,c) max(max(a,b),c) int main() { // freopen("data.in", "r", stdin); int n, x, t, m; while (~scanf("%d", &n) && n) { mst(dp, 0); m = 0; while (n--) { scanf("%d%d", &x, &t); ++dp[t][x + 1]; m = max(m, t); } for (int i = m - 1; i >= 0; --i) for (int j = 14; j >= 0; --j) dp[i][j] += max3(dp[i + 1][j], dp[i + 1][j - 1] , dp[i + 1][j + 1]); printf("%d ", dp[0][6]); } return 0; }