题目链接: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; }