贪心法:最佳浏览路线问题
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;
}
阿龙想到这个旅游街游玩,他的好友阿福给了他一些建议,用分值表示所有旅游街相邻两个路口之见的街道值得游览的程度,分值是从-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;
}
相关文章推荐
- 贪心法:最佳浏览路线问题
- 最佳浏览路线问题
- 最佳浏览路线问题
- 最佳浏览路线问题 算法设计
- 最佳浏览路线
- 部分背包问题(贪心)
- 理解动态规划算法与贪心算法区别----找钱问题
- 贪心专练1 区间调度最多问题
- bzoj 1052 覆盖问题 贪心 解题报告
- 【算法】贪心算法之背包与装箱问题
- 协议“ms-help://”无法识别导致msdn不能浏览问题的解决
- Uva 11134 Fabled Rooks (问题分解 + 贪心放置)
- 学员问题解答——向非关键路线要资源
- IE6下png透明问题解决的最佳方案
- HDOJ 2037 今年暑假不AC (贪心,区间排序问题)
- codevs1001 舒适的路线 贪心枚举+并查集
- POJ 2376 (区间问题,贪心)
- 2012长春网络赛 B题(贪心+multiset处理二维问题)
- Python基于回溯法子集树模板解决最佳作业调度问题示例
- nyoj 47 过河问题(贪心)