http://acm.hdu.edu.cn/showproblem.php?pid=1176

开始对dp有感觉了,就是能够覆盖所有的状态,而且要有状态转移方程,即递推关系。

那么这题就是,利用dp【i】【j】表示在第i秒在位置j可以获得的最大面包数,那么他可能从前一秒的左边,或者右边,或者原地不动来,那么着就是状态了。

对于0和10这两个点要特殊处理。

因为第一秒在位置5,所以初始化的时候要把第一秒的初始化了。

初始化:

dp[1][4]=map[1][4];
dp[1][5]=map[1][5];
dp[1][6]=map[1][6];

状态转移:

dp[i][j]=max(max(dp[i-1][j-1],dp[i-1][j+1]),dp[i-1][j])+map[i][j];

View Code
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#define maxn 150000
using namespace std;
int map[maxn][20];
int dp[maxn][20];
int n;
int main()
{
    while(scanf("%d",&n))
    {
        if(!n)break;
        memset(dp,0,sizeof(dp));
        memset(map,0,sizeof(map));
        int big=0;
        for(int i=0;i<n;i++)
        {
            int a,t;
            scanf("%d%d",&a,&t);
            map[t][a]++;
            big=max(big,t);
        }
        dp[1][4]=map[1][4];
        dp[1][5]=map[1][5];
        dp[1][6]=map[1][6];//初始化第一秒的有三个位置
        for(int i=2;i<=big;i++)//从第2秒到最大时间dp
        {
            for(int j=0;j<=10;j++)
            {
                if(j==0)
                    dp[i][j]=max(dp[i-1][j],dp[i-1][j+1])+map[i][j];//对于0点特殊
                else
                if(j==10)
                    dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+map[i][j];//对于10点特殊
                else
              dp[i][j]=max(max(dp[i-1][j-1],dp[i-1][j+1]),dp[i-1][j])+map[i][j];//状态转移
            }
        }
        int ans=0;
        for(int i=0;i<=10;i++)//遍历找出最大值
            ans=max(ans,dp[big][i]);
        printf("%d\n",ans);
    }
    return 0;
}
posted on 2012-08-29 00:34  一把刷子  阅读(150)  评论(0编辑  收藏  举报