方程比较简单的DP。
dp[t][x] = cnt[t][x] + max(dp[t+1][x], dp[t+1][x+1], dp[t+1][x-1])
总结:开始写成记忆化搜索爆栈了,然后发现 t 时刻完全可以由 t+1 推出,所以改成用循环来推就 AC 了。
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 102000;
int dpa[maxn][11];
int pie[maxn][11];
int n, maxt;
//记忆化搜索会爆栈
//int dp(int t, int x)
//{
// if(dpa[t][x] != -1) return dpa[t][x];
// if(t == maxt) return dpa[t][x] = pie[t][x];
// int ret = dp(t+1,x);
// if(x > 0 && dp(t+1,x-1) > ret) ret = dpa[t+1][x-1];
// if(x < 10 && dp(t+1,x+1) > ret) ret = dpa[t+1][x+1];
// ret += pie[t][x];
// return dpa[t][x] = ret;
//}
int main()
{
while(cin >> n && n != 0) {
memset(pie, 0, sizeof(pie));
maxt = 0;
for(int i = 0; i < n; i++) {
int x, t;
cin >> x >> t;
if(t > maxt) maxt = t;
pie[t][x]++;
}
memset(dpa, -1, sizeof(dpa));
for(int i = 0; i < 11; i++)
dpa[maxt][i] = pie[maxt][i];
for(int i = maxt-1; i >= 0; i--) {
for(int j = 0; j < 11; j++) {
int tmp = dpa[i+1][j];
if(j+1 < 11 && dpa[i+1][j+1] > tmp) tmp = dpa[i+1][j+1];
if(j > 0 && dpa[i+1][j-1] > tmp) tmp = dpa[i+1][j-1];
dpa[i][j] = pie[i][j] + tmp;
}
}
cout << dpa[0][5] << endl;
}
return 0;
}