这是一个矩阵的动态规划,与数塔问题类似。位置k和时间t是两个变量,假设在第t秒人·的位置在k处,用m[k][t]表示第t秒在位置k处人获得的最大饼的数量,那莫考虑考虑t-1秒时候人的位置k可以在k-1,k,k+1三个位置(当k=0或者k=10时候特殊处理)于是得到状态方程:
m[i][j]=max{m[i-1][j-1],m[i][j-1],m[i+1][j-1]}+a[i][j](其中a[i][j]表示第j秒掉在j位置的饼个数);
为了便于处理,将位置0-10用位置1-11来代替,于是初始位置5用6来代替,这样便于处理边界值。
#include<iostream>
using namespace std;
int a[13][100001];
int m[13][100001];/*m[i][j]表示第j秒在位置i-1处*/
int MaxPie(int n);
int max(int a, int b, int c);
int main(){
int n, s, t, i,j,Tmax=0;
while (cin >> n&&n){
for (i = 0; i < 13;i++)
for (j = 0; j < 100001; j++)
a[i][j] = m[i][j] = 0;
Tmax = 0;
for (i = 0; i<n; i++){
cin >> s >> t;
a[s + 1][t]++;
if (Tmax < t)
Tmax = t; //Tmax代表啦最大时间
}
cout << MaxPie(Tmax) << endl;
}
return 0;
}
int max(int a, int b, int c){
b = b > c ? b : c;
a = a > b ? a : b;
return a;
}
int MaxPie(int n){
int i, j, Max = 0;
for (j = 1; j <= n&&j<=5;j++)
for (i = 6 - j; i <= 6 + j; i++) /*先构建前面的三角形*/
m[i][j] = max(m[i - 1][j - 1], m[i][j - 1], m[i + 1][j - 1]) + a[i][j];
if (n > 5){ /*再构建后面矩形*/
for (j = 6; j <= n; j++)
for (i =1; i <=11; i++)
m[i][j] = max(m[i - 1][j - 1], m[i][j - 1], m[i + 1][j - 1]) + a[i][j];
}
for (i = 1; i <= 11; i++)
if (Max < m[i][n])
Max = m[i][n]; //找到第n秒的最大位置
return Max;
}