游玩景点
Time Limit:1000MS Memory Limit:65536K
Total Submit:182 Accepted:35
Description
DieIng五一要去旅游,旅游区的景点道路分布如图:欣赏景点的道路为东西走向,每条道路有DieIng对它的喜爱值;南北走向为林间小道,供休息用。
由于五一游客较多,旅游区规定欣赏景点的道路只能单向行走,自东向西走;林间小道可双向行走。
DieIng要你帮他设计路线(可以从任意点开始,任意点结束),使得他能玩得最high。(喜爱值的总和最大)
Input
第一行是两个整数N(0 <= N <= 10) 和M(0 <= M <= 1000000), 代表旅游区的布局,N*M
接下来N行,每行有M个整数favorite(-100 <= favorite<=100)
N,M==0结束。
Output
输出DieIng能得到最大的喜爱值总和。
Sample Input
3 4
5 -4 6 14
-2 -48 11 -8
9 -13 4 8
0 0
Sample Output
30
Source
GDUT Programming Contest 2009 by longshen
/* ----------------------------------------------------------------------------------
大概想法:
1、看到的题目的要输入最大值的时候,第一感觉就是要用DP或者贪心来做,然后再去看看有
没有最优子结构什么的,果然有,最后通过的景点最大值必然是以最大值通过前一个景点,
然后什么独立子问题的不会分析,先试试用DP。
2、在写递归解的时候,突然间觉得这个题目貌似见过。题目的示例输出是30,也就是每一列的
最大值加起来。如果用暴力法求解的话,就需要遍历出每一列的最大值,然后根据逐一相加
求出最大值,这样做的话估计会超时。可不可以降低时间复杂度?刚才说到了“其实就是求
出每一列的最大值”,这一句提示了我。我可以求出每一列的最大值,然后将它们放到另外
一个数组中或者覆盖原数组中该元素的位置,从而构造出一个由列最大值组成的数组,然后
再来看看,这一个问题其实就转化为求最大子数组之和的问题。
详细见代码
---------------------------------------------------------------------------------- */
#include<stdio.h>
#define max(x,y) ((x)>(y) ? (x) : (y))
long a[1000004] ;
long b[1000004] ; //空间其实也可以优化,覆盖原来的位置
int main(void)
{
long N = 0 ;
long M = 0 ;
long i = 0 ;
long j = 0 ;
long nFavSum = 0 ;
long nTemp = 0 ;
long nTotal = 0 ;
while(scanf("%ld%ld",&N,&M), (N != 0 && M != 0))
{
nFavSum = 0 ;
nTemp = 0 ;
nTotal = 0 ;
for(i = 0 ; i < N ; ++i)
{
for(j = 0 ; j < M ; ++j)
{
scanf("%ld",&nTemp) ;
if(0 == i)
{
a[nTotal++] = nTemp ;
}
else if(nTemp > a[j])
{
a[j] = nTemp ;
}
}
}
b[0] = a[0] ;
nFavSum = 0 ;
for(i = 1 ; i < M ; ++i)
{
b[i] = max(a[i],b[i-1]+a[i]) ;
if(nFavSum < b[i])
{
nFavSum = b[i] ;
}
}
printf("%ld\n",nFavSum) ;
}
return 0 ;
}