http://acm.hdu.edu.cn/showproblem.php?pid=1176
首先可以处理出整张地图的状态。
book[T][POS]表示第T秒,在第pos个地方有多少个馅饼。
dp[i][j]表示第i秒的时候,在第j个位置能得到的最大值。
边界值:dp[1][4] = book[1][4]; dp[1][5] = book[1][5]; dp[1][6] = book[1][6];
因为一开始一步只能走到这里。
然后转移枚举下一秒的时候,由上面的状态选一个最大的枚举下来。
因为只和上一唯有关,所以可以用滚动数组来实现。
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> const int maxn = 1e5 + 20; int n; int book[maxn][12]; int dp[2][12]; void work() { memset(book, 0, sizeof book); memset(dp, 0, sizeof dp); int mx = -inf; for (int i = 1; i <= n; ++i) { int T, pos; scanf("%d%d", &pos, &T); book[T][pos]++; mx = max(mx, T); } dp[1][5] = book[1][5]; dp[1][4] = book[1][4]; dp[1][6] = book[1][6]; int now = 0; for (int i = 2; i <= mx; ++i) { for (int j = 0; j <= 10; ++j) { if (j == 0) { dp[now][j] = max(dp[!now][j], dp[!now][j + 1]) + book[i][j]; } else if (j == 10) { dp[now][j] = max(dp[!now][j - 1], dp[!now][j]) + book[i][j]; } else { dp[now][j] = max(dp[!now][j - 1], max(dp[!now][j], dp[!now][j + 1])) + book[i][j]; } } now = !now; } int ans = -inf; for (int i = 0; i <= 10; ++i) ans = max(ans, dp[!now][i]); printf("%d ", ans); } int main() { #ifdef local freopen("data.txt","r",stdin); #endif while (scanf("%d", &n) && n) work(); return 0; }