hdu 1176 dp(数塔)

View Code
//hdu 1176  dp(数塔)

//简单dp,刚在练dp,一些小错误,纠结了好就
//可以从前往后推 也可以从后往前推
//我是从前(时间 为1, 位置为5)往后推的,这样比较纠结,还要限制
//前几步不能走太远,因为一秒只能移动一格,要记录最优值
//如果从最后一秒往前推的话,可以省掉一些判断,结果直接输出dp[0][5]就可以了



#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
#define N 100005

//前一维表示时间,后一维表示坐标
int cake[N][15], dp[N][15];

int main()
{
    int n_cake;
    while(scanf("%d", &n_cake), n_cake)
    {
        memset(cake, 0, sizeof(cake));
        memset(dp, 0, sizeof(dp));

        int max_t = 0;
        while(n_cake--)
        {
            int point, time;
            scanf("%d%d", &point, &time);
            cake[time][point]++;    //记录time时间在point点掉几块
            max_t = max(max_t, time);   //记录最大时间
        }

        int max_cake = 0;
        //第一重循环表示在 时间 i 的时候
        //第二重循环表示 时间 i 时,人在 j 位置
        for(int i = 1; i <= max_t; ++i)
        {
            for(int j = 0; j <= 10; ++j)
            {   //记录时间 i-1 时 j 位置的 cake 数
                int num = dp[i-1][j];

                //记录前一时刻所能到 i时刻 j 位置的状态下,最多的cake数
                if(j != 0)
                    num = max( num, dp[i-1][j-1] );
                if(j != 10)
                    num = max( num, dp[i-1][j+1] );

                dp[i][j] = num;

                //i 时刻 j位置为 前一状态 最优值 加上 现在状态的值
                if( cake[i][j] && i >= abs(j - 5) ) //表示从 5 开始,比如时间为 1时到不了3
                    dp[i][j] += cake[i][j];

//                if(i == 1 && (j < 4 || j > 6))  //判断前几步时不能这样判断,不过
//                    continue;             //这题的数据太水,被我水过了

                max_cake = max(max_cake, dp[i][j]);
            }
        }
        printf("%d\n", max_cake);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/gabo/p/2445027.html