您的位置:首页 > 其它

贪心法:最佳浏览路线问题

2018-01-18 18:00 204 查看
(最佳游览线路问题  教材第四章 第11题) 某旅游区的街道成网格状。其中东西向的街道都是旅游街,南北向的街道都是林阴道。由于游客众多,旅游街被规定为单行道,游客在旅游街上只能从西向东走,在林阴道上则既可从南向北走,也可以从北向南走。 
阿龙想到这个旅游街游玩,他的好友阿福给了他一些建议,用分值表示所有旅游街相邻两个路口之见的街道值得游览的程度,分值是从-100到100的整数,所有林阴道不打分。所有分值不可能全是负分。如图:


解题思路:本题的主要思想为贪心,贪心策略为:我们可以假设阿龙在每组处在同一纵向的旅游街上都要选择一条旅游街,为了使旅游线路的总分值最大,则应选择每组中分值最大的旅游街,将所有分值最大的旅游街存入一个数组中。因为阿龙可以从任意路口开始游览,也可以在任意路口结束游览,所以要求旅游线路的最大总分值,就要在我们存的数组中找出一个和最大的连续子序列。需要注意的是,要求最大连续子序列,可以先进行预处理(计算出前缀和),以节省时间。
#include<stdio.h>

int maxSub(int a[]);//求最大子序列和
int main(void)
{
int a[5][3]={
{-50,17,-42},
{-47,-19,-3},
{36,-34,-43},
{-30,-43,34},
{-23,-8,-45}
};
int i,j;
int max,n;
int maxRoute=0;
int route[10];//用来存放旅游街每一列的最大分值
for(i=0;i<5;i++)
{
max=a[i][0];//max为第i行的最大分值
n=0;//最大分值列号
for(j=0;j<3;j++)//遍历每一行元素
{
if(a[i][j]>max)
{
max=a[i][j];
n=j;
}
}
route[i]=max;
printf("a[%d][%d]=%d\n",i,n,max);
}
maxRoute=maxSub(route);
printf("最佳路线长度为:%d\n",maxRoute);
return 0;
}

/*
在我们存的数组中找出一个和最大的连续子序列
①任何负的子序列都不可能是最大子序列和的前缀
②当加上下标j所在的元素,使得当前序列的和变成负数时,根据①,可以从j+1处重新开始计算下一段子序列的和。
因为某段子序列到索引j位置时,它们的和是负的,意味着最大子序列不会包含这一段子序列,那么从j+1开始,看能不能找到一段更大的子序列。
*/
int maxSub(int a[])
{
int maxSum=0,headSum=0;
int i;
for(i=0; i<5; i++)
{
headSum+=a[i];
if(headSum>maxSum)
maxSum=headSum;
else if(headSum<0)
headSum=0;
}
return maxSum;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: