HDU 1176 免费馅饼

感谢sjy巨巨的帮助,一开始知道这是一道dp题但就是找不到思路,经过sjy巨巨的指点才搞懂。

这道题是以每一秒为一个状态,遍历一遍坐标,状态是从最后一秒往前遍历。

就样例来说的话,最后一秒是第3秒,坐标是8。那么此时的状态可以由第2秒的时间,坐标7,8,9三个位置过来。

用一个二维数组,下标分别表示时间 t 和 位置 x。可以得到 dp[x][t]=max( dp[x][t],dp[y][t-1]+dp[x][t] ) 『y 从 x-1 循环到x+1,因为x的位置可以由这三个位置到达』;

  

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int dp[100010][15];
int t,n,x,y;
int main()
{

    while(scanf("%d",&n)!=EOF,n)
    {
        int mm=0;
        memset(dp,0,sizeof(dp));
        for(int i=0; i<n; i++)
        {
            scanf("%d%d",&x,&y);
            dp[y][x+1]++;
//这个地方也是sjy同学想出来的,因为在0和10的位置上分别只能由 -1,1,2 和9,10,11到达,
//而-1和11都不存在,所以可以看着是0。也就是说从-1 11到达0和10的时候本身提供的价值就是0;
//and 因为数组的最小值是0,不存在-1 所以右移一位,让x=0,代替x=-1的位置。
            mm=max(y,mm);
        }
        for(int i=mm-1; i>=0; i--)
        {
            for(int j=1; j<=11; j++)
            {
                for(int k=j-1; k<=j+1; k++)
                {
                    dp[i][j]=max(dp[i][j],dp[i+1][k]+dp[i][j]);
                }
            }
        }
        printf("%d\n",dp[0][6]);
    }
    return 0;
}

 

posted @ 2015-10-31 14:34  zzuli_柚子  阅读(104)  评论(0编辑  收藏  举报