杭电1087 Super Jumping! Jumping! Jumping!(初见DP)

时间:2021-07-24 22:21:51

Super Jumping! Jumping! Jumping!

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 40030    Accepted Submission(s): 18437


Problem Description Nowadays, a kind of chess game called “Super Jumping! Jumping! Jumping!” is very popular in HDU. Maybe you are a good boy, and know little about this game, so I introduce it to you now.

杭电1087 Super Jumping! Jumping! Jumping!(初见DP)


The game can be played by two or more than two players. It consists of a chessboard(棋盘)and some chessmen(棋子), and all chessmen are marked by a positive integer or “start” or “end”. The player starts from start-point and must jumps into end-point finally. In the course of jumping, the player will visit the chessmen in the path, but everyone must jumps from one chessman to another absolutely bigger (you can assume start-point is a minimum and end-point is a maximum.). And all players cannot go backwards. One jumping can go from a chessman to next, also can go across many chessmen, and even you can straightly get to end-point from start-point. Of course you get zero point in this situation. A player is a winner if and only if he can get a bigger score according to his jumping solution. Note that your score comes from the sum of value on the chessmen in you jumping path.
Your task is to output the maximum value according to the given chessmen list.
 

 

Input Input contains multiple test cases. Each test case is described in a line as follow:
N value_1 value_2 …value_N 
It is guarantied that N is not more than 1000 and all value_i are in the range of 32-int.
A test case starting with 0 terminates the input and this test case is not to be processed.
 

 

Output For each case, print the maximum according to rules, and one line one case.  

 

Sample Input 3 1 3 24 1 2 3 44 3 3 2 10  

 

Sample Output 4 10 3

 题目大意:就是有一种棋,从起点到终点有很多路径,从一个点跳x到另一个点b,如果b点的值(a[b])比b之前的某些点值大,那b的dp[b]就等于b+之前的某些点中max(dp[某些点之一]),然后求出最大的。有点像最大子串问题。

举几个例子就明白了

比如一组数为 1 2 3 4 1 2 3 4 5

那么  a[0]=1      a[1]=2    a[2]=3        a[3]=4        a[4]=1                                                      a[5]=2                                                                         a[6]=3       a[7]=4           a[8]=5

        dp[0]=1  dp[1]=3    dp[2]=6       dp[4]=10     dp[4]=1(因为a[4]之前没有比他小的)        dp[5]=3(有个a[0]比它小,然后a[4]不能重复加)      dp[6]=6      dp[7]=10       dp[8]=15

      然后 max=15  

    同理 另一组数  10 6 10 7 10 8 10 9 的max=31=6+7+8+10

然后奉上代码:

#include <iostream>
#include
<math.h>
#include
<iomanip>
#include
<cstdio>
#include
<string>
#include
<map>
#include
<vector>
#include
<list>
#include
<algorithm>
#include
<stdlib.h>
#include
<iterator>
#include
<sstream>
#include
<string.h>
#include
<stdio.h>
using namespace std;
int main()
{
int n;
int a[1001];
int dp[1001];
while(cin>>n)
{
if(n==0)
{
break;
}
for(int ii=0;ii<n;ii++)
{
cin
>>a[ii];//读数
}
dp[
0]=a[0];//第一个数的最大和肯定就是第一个数
for(int i=0;i<n;i++)
{
dp[i]
=a[i];//将最初的dp[i]赋值为它本身
for(int j=0;j<i;j++)//开始对i之前的数进行扫描
{
if(a[i]>a[j]&&a[i]+dp[j]>dp[i])
{
//前一个条件是为了递增
//后一个条件是为了防止遇到小的就加,也保证dp[i]取到最大
dp[i]=a[i]+dp[j];
}
}
}
int max=dp[0];
for(int i=1;i<n;i++)
{
if(dp[i]>max)
{
max
=dp[i];
}
}
cout
<<max<<endl;
}
return 0;


}

 

 这题 我开始没弄懂,还以为是找最子串,后来发现并不是。这算是第一题DP吧,还是参考了网上的代码的,希望之后能自己写。