描述
如今,一种国际象棋游戏叫做“超级跳跃!跳!跳跃!“在HDU中非常受欢迎。也许你是个好孩子,对这个游戏知之甚少,所以我现在把它介绍给你。
游戏可以由两个或两个以上的玩家玩。它由棋盘(棋盘)和一些棋子(棋子)组成,所有棋手都用正整数或“开始”或“结束”标记。玩家从起点开始,最后必须跳到终点。在跳跃过程中,玩家将访问路径中的棋手,但每个人都必须从一个棋手跳到另一个绝对更大的棋手(您可以假设起点是最小值,终点是最大值)。所有玩家都不能倒退。一个跳跃可以从一个棋手跳到另一个棋手,也可以跨越许多棋手,甚至你可以从起点直接到达终点。当然,在这种情况下你会得到零分。当且仅当一名球员能够根据他的跳跃解决方案获得更大的分数时,他才是赢家。请注意,您的分数来自跳跃路径中棋手的价值总和。
您的任务是根据给定的棋手列表输出最大值。
游戏可以由两个或两个以上的玩家玩。它由棋盘(棋盘)和一些棋子(棋子)组成,所有棋手都用正整数或“开始”或“结束”标记。玩家从起点开始,最后必须跳到终点。在跳跃过程中,玩家将访问路径中的棋手,但每个人都必须从一个棋手跳到另一个绝对更大的棋手(您可以假设起点是最小值,终点是最大值)。所有玩家都不能倒退。一个跳跃可以从一个棋手跳到另一个棋手,也可以跨越许多棋手,甚至你可以从起点直接到达终点。当然,在这种情况下你会得到零分。当且仅当一名球员能够根据他的跳跃解决方案获得更大的分数时,他才是赢家。请注意,您的分数来自跳跃路径中棋手的价值总和。
您的任务是根据给定的棋手列表输出最大值。
输入
输入包含多个测试用例。每个测试用例在一行中描述如下:
N value_1 value_2...
value_N 可以保证 N 不超过 1000,并且所有value_i都在 32-int 的范围内。
以 0 开头的测试用例将终止输入,并且不会处理此测试用例。
N value_1 value_2...
value_N 可以保证 N 不超过 1000,并且所有value_i都在 32-int 的范围内。
以 0 开头的测试用例将终止输入,并且不会处理此测试用例。
输出
对于每个事例,根据规则打印最大值,并打印一行一个事例。
示例输入
3 1 3 2
4 1 2 3 4
4 3 3 2 1
0
示例输出
4
10
3
分析:其实就一最大升序子序列和。我有两种思路,第一种自己根据学得动态规划,用的野路子,WA了。第二种,发现思路和我差不多,改的模板。
先展示AC代码:
#include<iostream>
#include<algorithm>
#define MAXN 1010
using namespace std;
int n;
int main()//需要动态规划基础。
{
while(scanf("%d", &n) && n)
{
int a[MAXN], maxlen=0, pos;
int f[MAXN], pre[MAXN];
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
f[i] = a[i];//边界
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= i - 1; j++)
{
if (a[j] < a[i])//第i个数之前比他小的数
f[i] = max(f[i], f[j] + a[i]);//取当前值和被经历的,留下最大的。
}
maxlen = max(maxlen, f[i]);//找出存的最大的数。
}
printf("%d\n", maxlen);
}
return 0;
}
WA代码(大家可以帮我找找错,我真不知道哪错了)
//#include<iostream>
//#include<stdio.h>
//#include<algorithm>
//using namespace std;
//int n,a[1005],dp[1005];//a是输入元素,dp是用来储存最大值的(动态规划)
//int main()
//{
//
// while (scanf("%d", &n) && n != 0)
// {
// for (int i = 1; i <= n; i++)
// {
// scanf("%d", &a[i]);
// dp[i] = a[i];//边界点
// }
// for (int i = 1; i <= n; i++)//从每个点出发
// {
// int flag = i;//标记一个点,不断更新j(比现在更大的值)
// for (int j = i; j <= n; j++)//遍历i之后的点
// if (a[flag] < a[j])//根据题意,我们选择更大的点
// {
// dp[j] = max(dp[j], dp[flag] + a[j]);//如果还没有经历过,更新为两数和。否则,留下最大的经历和。
// flag = j;//标记这个点,再找比这个更大的数
// }
// }
// int m = 0;
// for (int i = 1; i <= n; i++)//找经历的所有中最大数。
// m = max(m, dp[i]);
// printf("%d\n", m);
// }
// return 0;
//}