运用方法:动态划归
问题描述:
如今,一种被称为“超级跳!跳!跳!”的棋类游戏在杭电很流行。也许你是一个好孩子,多少了解这个游戏,所以我给你介绍一下。

这个游戏可两个或者两人以上进行。它包含一个棋盘和一些棋子,所有棋子标记一个正整数或“开始”或“结束”。玩家开始于开始点,必须最终跳到终止点。在跳的期间(in the course of jumping),玩家将会在路劲中访问棋子,但是所有人必须从一个棋子到另一个绝对大处(你可以假设开始点是一个最小的,终止点是一个最大的。)。所有玩家不能悔棋。每一跳可以从一个棋子去另一个,也可以越过很多棋子,甚至你可以直接从起始点到终止点。当然这种情况下你只能得零分。胜利者必须能用他的解决方案获得最高的分数。你的成绩来源于你所跳过路径的棋子值之和。
你的任务是根据所给的棋子列表输出最大值。
输入:
输入包含多个测试样例。每个测试样例描述为如下一行:
N value_1 value_2 …value_N
必须保证N不大于1000,所有的value_i在32-int范围内(in the range of)。
一个测试样例以0开始且终止输入,则这个测试样例不会被处理。
输出:
对于每一个样例,根据规则打印最大值,一行一个样例。
Sample Input
3 1 3 2
4 1 2 3 4
4 3 3 2 1
0
Sample Output
4
10
3
题目思路:
注意,求解最大递增子序列和,这里要特别注意一点:这个题目不要求是连续的最大递增子序列。但是一定要注意是递增的。
dp数组表示是包含当前这个数的最大递增子序列和。dp[i]表示的是前i个并且包含第i个的最大递增子序列和!给个数据:3 1 4 显然dp[1]=3,dp[2]=1表示两个数的最大值。因为分两种情况讨论,如果第二个数大于第一个数,就加上,即dp[2]=dp[1]+num[2];如果不大,dp[2]=num[2]; dp[3]=7表示三个数的最大值。首先比较num[3]和num[1],如果num[3]>num[1],dp[3]=7先存下来,如果num[3]>num[2],dp[3]=5依旧存下来;还有一种如果num[3]比前两个值都小,dp[3]=num[3];最后在存下来的dp[3]中找到一个最大的!
AC代码:
Online Judge Online Exercise Online Teaching Online Contests Exercise Author F.A.Q Hand In Hand Online Acmers Forum | Discuss Statistical Charts Problem Archive Realtime Judge Status Authors Ranklist Search C/C++/Java Exams ACM Steps Go to Job Contest LiveCast ICPC@China Best Coder beta VIP | STD Contests Virtual Contests DIY | Web-DIY beta Recent Contests Author hsinhsia Mail Mail 0(0) Control Panel Control Panel Sign Out Sign Out View Code Problem : 1087 ( Super Jumping! Jumping! Jumping! ) Judge Status : Accepted RunId : 23388301 Language : G++ Author : hsinhsia Code Render Status : Rendered By HDOJ G++ Code Render Version 0.01 Beta #include <iostream> #include <cstdio> #include <cstring> using namespace std; int num[1010],dp[1010]; int main () { int n,Max; while (~scanf("%d",&n)) { if (n==0) break; Max=0; memset(dp,0,sizeof(dp)); for (int i=0;i<n;i++) { scanf("%d",&num[i]); } dp[0]=num[0]; for (int i=1;i<n;i++) { for (int j=0;j<i;j++) { if (num[i]>num[j]) dp[i]=max(dp[i],dp[j]+num[i]); } dp[i]=max(dp[i],num[i]); } for (int i=0;i<n;i++) { Max=max(Max,dp[i]); } printf ("%d\n",Max); } return 0; }
问题代码:
#include <cstdio> #include <cstring> #include <algorithm> const int MAXN = 1000; //record the maximum of sub-string int dp[MAXN]; //record the input number int num[MAXN]; using namespace std; bool cmp(int a, int b){ //order by decreasing return a > b; } int main(){ // ~是按位取反 //scanf的返回值是输入值的个数 //如果没有输入值就是返回-1 //-1按位取反结果是0 //while(~scanf("%d", &n))就是当没有输入的时候退出循环 int n; while(~scanf("%d",&n)){ if(n == 0) break; //initialize the dp memset(dp, -1, sizeof(int)); for(int i = 0; i < n; i++){ scanf("%d",&num[i]); } dp[0] = num[0]; for(int i = 1; i <= n; i++){ if(num[i-1] < num[i]){ dp[i] = dp[i-1] + num[i]; } else dp[i] = num[i]; } sort(dp,dp+n,cmp); printf("%d\n", dp[0]); } return 0; }
浙公网安备 33010602011771号