题目链接:HDU 1176 免费馅饼
数塔变形。
自底向上,画出数塔图可以发现五秒后(包括五秒)可以达到的点都是一样的,所以需要注意边界处理。
状态转移方程:dp[i][j]=max(dp[i+1][j-1],dp[i+1][j],dp[i+1][j+1])+value[i][j]。i表示第i秒,j表示位置,dp[i][j]表示第i秒在位置j所能取到的最大值。
dp[0][5]就是答案。
直接给dp数组赋值可以把value数组省了。
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
const int MAX_N = 100000 + 1000;
//int value[MAX_N][12];
int dp[MAX_N][12];
int t,n,x;
int main()
{
while(scanf("%d",&n),n)
{
memset(dp,0,sizeof(dp));
/*memset(value,0,sizeof(value));*/
int time,location;
int _max_time = -1;
for(int i = 0;i < n;i++)
{
scanf("%d%d",&location,&time);
//value[time][location]++;
dp[time][location]++;
_max_time = max(_max_time,time);
}
/*for(int i = 0;i <= 10;i++)
dp[_max_time][i] = value[_max_time][i];*/
for(int i = _max_time - 1;i >= 0;i--)
{
if(i >= 5)
{
for(int j = 0;j <= 10;j++)
{
if(j == 0)
dp[i][j] += max(dp[i + 1][j],dp[i + 1][j + 1]) /*+ value[i][j]*/;
else if(j == 10)
dp[i][j] += max(dp[i + 1][j],dp[i + 1][j - 1]) /*+ value[i][j]*/;
else
dp[i][j] += max(max(dp[i + 1][j],dp[i + 1][j + 1]),dp[i + 1][j - 1]) /*+ value[i][j]*/;
}
}
else
{
for(int j = 5 - i;j <= 5 + i;j++)
dp[i][j] += max(max(dp[i + 1][j],dp[i + 1][j + 1]),dp[i + 1][j - 1]) /*+ value[i][j]*/;
}
}
cout << dp[0][5] << endl;
}
return 0;
}