HDOJ-1087-Super Jumping! Jumping! Jumping! 解题报告

       简单动态规划题(这题目名字好长啊、、、),好像我以前看到了那啥类似的最长上升子序列的题。题目大意:在杭电有这么一种棋类游戏,在棋盘中有起点和终点,起点和终点之间的点用数字标记,代表到达该点可获得的分数,每个人只能从起点出发,每次走一步走到下一个点就能获得该点的分数(走步时不能走到比当前点分数小的点上,也不能往回走),可以一次跨越多个点但前提是该点分数比走步前的点的分数高,比如直接从起点走到终点(起点视为分数最小,终点视为分数最大)。给你每个点的分数,求从起点到达终点后可以获得的最大分数。


       我的解题思路:我们假设dp[i]是从起点到达i点时可获得的最大分数,num[i]是i点的分数,那么容易通过题意得知该点的状态转移公式为dp[i] = max(dp[i], dp[x1] + num[i], ....dp[xn] + num[i]),其中xn是每一个点分数不大于num[i]的点且在点i前面的点。首先初始化的话dp[i] = num[i],这是毋庸置疑的。然后根据状态转移方程可知答案就是其中最大的dp。


       下面是我的解题代码:

#include 
#include 
#include 
#include 

using namespace std;

#define N 1111

int n;
int num[N];     //存储该点的分数
int dp[N];      //存储到达该点可得的最大分

void Read();        //输入

void DataProcess(); //解题

int main()
{
    while (~scanf("%d", &n))
    {
        if (n == 0) break;
        Read();
        DataProcess();
    }
    return 0;
}

void Read()
{
    for (int i=1; i<=n; ++i)
    {
        scanf("%d", &num[i]);
        dp[i] = num[i];         //附带初始化
    }
    dp[0] = num[0] = 0;     //初始化,重要部分
    return;
}

void DataProcess()
{
    int ans = 0;
    for (int i=1; i<=n; ++i)
    {
        for (int j=i+1; j<=n; ++j)
        {
            if (num[j] > num[i])
            {
                dp[j] = max(dp[j], dp[i] + num[j]);
            }
        }
        ans = max(dp[i], ans);
    }
    printf("%d\n", ans);
    return;
}

你可能感兴趣的:(ACM题解,【动态规划】,HDOJ,题解,ACM解题报告)