游玩景点
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 ; }