贪心算法,n分解成自然数只和,求最大成绩问题

贪心算法,n分解成自然数只和,求最大成绩问题
贪心算法,n分解成自然数只和,求最大成绩问题

《算法设计与分析》

上机实验报告

专业软件工程

班级软件1101

学号04113033

学生姓名岳彦利

完成日期2013-11-26

1. 上机题目及实验环境

1.1上机题目:最优分解问题

1.2实验环境:

CPU:英特尔第二代酷睿i3-2330M @2.2GHz 双核

内存:4G

操作系统:windows 7

软件平台:ubuntu

2.算法设计与分析

1.对于 n <= 4,可以验证其分解成几个正整数的和的乘积是小于 n 的。

2.对于 n >4, 能证明其能分解成几个数的和使得乘积不小于 n。如果分解成 1 和 n - 1,那么对乘积是没有帮助的,因此,假设 n分解成 a 和 n - a,2 <= a <= n - 2.如果 a, n - a 仍然 > 4,那么继续分解,直至 a, n - a <= 4。因为每次分解都能使乘积增加,所以最优解必是最终分解结果,也即分解出的数全是 2 或 3 .

3.若1作因数,则显然乘积不会最大。把m分拆成若干个互不相等的自然数的和,因数个数越多,乘积越大。为了使因数个数尽可能地多,我们把m分成2+3…+n直到和大于等于m。若和比m大1,则因数个数至少减少1个,为了使乘积最大,应去掉最小的2,并将最后一个数(最大)加上1。若和比m大k(k≠1),则去掉等于k的那个数,便可使乘积最大。

3.核心代码

int BestDecomepose(int *a)//求自然乘机的最大和

{

int i,j;

int d,r=1,sum=0;

for(i=2;;i++)

{

sum+=i;

d=(sum-*a);

if(d>=0)

break;

}

printf("组成最大成绩的自然数分别是:\n");

if(d==1)

{

for(j=3;j

{

r*=j;

printf("%d ",j);

}

++i;

printf("%d \n",i);

r*=i;

}

else

{

for(j=2;j<=i;j++)

{

if(j==d) //如果j和d相等,就不执行continue下面的语句了continue;

r*=j;

printf("%d ",j);

}

printf("\n");

}

return r;

}

4.运行与调试

图一.写程序时遇到的问题

图二.大于4的三中情况截图

图三.小于等于4的其中一种情况截图

5. 结果分析和小结

如图一,是在写程序时,在大于4的时候里面的循环写错了,经过调试修改,输出正确,如图二和三。

如图二, 是大于4的测试数据。在input.txt第一行中第一个数代表输入的数,第二行数代表组成这个数的最大成绩的个数。这三组测试数都是自由生成的。

如图三,是另一组小于或等于4的其中一种测试结果。

(2)本次上机实验的收获、心得体会。

这次的上机实验,使我对贪心算法法有了一定的认识,编程的时候也有了更多的思路,在编程之前一定把思路清晰,这样写的时候就比较轻松了。以前对这种数学问题不是很在意,现在觉得学这门课还得多看看数学这方面的知识,从而能更好的学好这门课。

附录(C/C++源代码)

#include

#include

#include

#include

#include

int BestDecomepose(int *a)//求自然乘机的最大和

{

int i,j;

int d,r=1,sum=0;

for(i=2;;i++)

{

sum+=i;

d=(sum-*a);

if(d>=0)

break;

}

printf("组成最大成绩的自然数分别是:\n");

if(d==1)

{

for(j=3;j

{

r*=j;

printf("%d ",j);

}

++i;

printf("%d \n",i);

r*=i;

}

else

{

for(j=2;j<=i;j++)

{

if(j==d) //如果j和d相等,就不执行continue下面的语句了continue;

r*=j;

printf("%d ",j);

}

printf("\n");

}

return r;

}

main()

{

FILE *fp,*fp1;

int a,max;

fp=fopen("input1.txt","wt");//将随机数写入文件

if(fp==NULL)

{

printf("Conot open the file!");

exit(0);

}

srand((int)time(0));//避免和上次取得数相同

a=1+(int)(25.0*rand()/(RAND_MAX+1.0));//取随机数

fprintf(fp,"%d",a);

printf("Input1.txt:\n");

printf("%d\n",a);

fclose(fp);

if(a>4)//当输入的数大于4的情况

{

max=BestDecomepose(&a);

fp1=fopen("output1.txt","wt");//将大于4的结果写入文件 if(fp1==NULL)

{

printf("Conot open the file!");

exit(0);

}

fprintf(fp1,"%d",max);

fclose(fp1);

}

else

{

fp1=fopen("output1.txt","wt");//将小于等于4的结果写入文件

if(fp1==NULL)

{

printf("Conot open the file!"); exit(0);

}

fprintf(fp1,"%d",a-1);

fclose(fp1);

}

printf("output1.txt:\n"); //输出文件里的类容 fp1=fopen("output1.txt","rt");

if(fp1==NULL)

{

printf("Conot open the file!"); exit(0);

}

fscanf(fp1,"%d",&max);

printf("%d\n",max);

fclose(fp1);

}

贪心算法经典例题

贪心算法经典例题 发布日期:2009-1-8 浏览次数:1180 本资料需要注册并登录后才能下载! ·用户名密码验证码找回密码·您还未注册?请注册 您的账户余额为元,余额已不足,请充值。 您的账户余额为元。此购买将从您的账户中扣除费用0.0元。 内容介绍>> 贪心算法经典例题 在求最优解问题的过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次的贪心选择,最终得出整个问题的最优解,这种求解方法就是贪心算法。 从贪心算法的定义可以看出,贪心法并不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解。 我们看看下面的例子 例1 均分纸牌(NOIP2002tg) [问题描述] 有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若干张纸牌,然后移动。移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。例如 N=4,4 堆纸牌数分别为: ①9 ②8 ③17 ④ 6 移动3次可达到目的: 从③取 4 张牌放到④(9 8 13 10) -> 从③取 3 张牌放到②(9 11 10 10)-> 从②取 1 张牌放到①(10 10 10 10)。 [输入]:键盘输入文件名。 文件格式:N(N 堆纸牌,1 <= N <= 100) A1 A2 … An (N 堆纸牌,每堆纸牌初始数,l<= Ai <=10000) [输出]:输出至屏幕。格式为:所有堆均达到相等时的最少移动次数。 [输入输出样例] a.in: 4 9 8 17 6 屏慕显示:3 算法分析:设a[i]为第i堆纸牌的张数(0<=i<=n),v为均分后每堆纸牌的张数,s为最小移到次数。 我们用贪心法,按照从左到右的顺序移动纸牌。如第i堆(0

算法设计实验_贪心算法背包问题

《算法分析与设计》 课程实验 专业年级:信息与计算科学 学生学号: 学生姓名: 实验题目:用贪婪法求解背包问题 指导老师: 实验时间:20xx年xx月x日 一、实验内容 用贪婪法求解背包问题 要求:用非递归实现 二、实验步骤 2.1、理解算法思想和问题要求; 2.2、写出每个操作的算法 非递归算法: greedbag() { int N; int c;

int[] w; int[] v; Scanner scan=new Scanner(System.in); System.out.print("输入背包的容量:"); c=scan.nextInt(); System.out.print("输入物品的数量:"); N=scan.nextInt(); System.out.print("分别输入物品的价值:"); v=new int[N]; for(int i=0;i

贪心算法 找零钱问题

学号 《算法设计与分析》 实验报告三 学生姓名 专业、班级 指导教师 成绩 电子与信息工程系

实验三:贪心算法运用练习 一、实验目的 本次实验是针对贪心算法运用的算法设计及应用练习,旨在加深学生对该部分知识点的理解,提高学生运用该部分知识解决问题的能力。 二、实验步骤与要求 1.实验前复习课程所学知识以及阅读和理解指定的课外阅读材料; 2.学生独自完成实验指定内容; 3.实验结束后,用统一的实验报告模板编写实验报告。 4.提交说明: (1)电子版提交说明: a 需要提交Winrar压缩包,文件名为“《算法设计与分析》实验二_学号_姓名”, 如“《算法设计与分析》实验二_09290101_张三”。 b 压缩包内为一个“《算法设计与分析》实验二_学号_姓名”命名的顶层文件夹, 其下为两个文件夹,一个文件夹命名为“源程序”,另一个文件夹命名为“实验 报告电子版”。其下分别放置对应实验成果物。 (2)打印版提交说明: a 不可随意更改模板样式。 b 字体:中文为宋体,大小为10号字,英文为Time New Roman,大小为10号 字。 c 行间距:单倍行距。 (3)提交截止时间:2012年12月7日16:00。 三、实验项目 1.传统的找零钱问题的算法及程序实现。 2.特殊的0-1背包问题的求解:本次求解的0-1背包问题的特点为每种物品各有M件,已知每个物品的单位价值,求使得所获价值最大的装包方案。 四、实验过程 找零钱问题: #include using namespace std; void Zl(double num) { int leave=0; int a[8]; leave = (int)(num*10)%10; a[1] = leave/5;

C语言版贪心算法背包问题

#include<> #define N 100 typedef struct bao{ int num; float w; float v; }; typedef struct avg{ int num; ( float val; float w; float v; }; struct bao b[N]; struct avg d[N]; int n; float c; ^ void Sort() { int i,j,k; struct avg temp[N]; for(i=0;i

float x[N],sum = 0; for(i=0;ic) break; x[d[i].num] = 1; sum += d[i].v; c -= d[i].w; } if(i

0023算法笔记——【贪心算法】哈夫曼编码问题

0023算法笔记——【贪心算法】哈夫曼编码问题 1、问题描述 哈夫曼编码是广泛地用于数据文件压缩的十分有效的编码方法。其压缩率通常在20%~90%之间。哈夫曼编码算法用字符在文件中出现的频率表来建立一个用0,1串表示各字符的最优表示方式。一个包含100,000个字符的文件,各字符出现频率不同,如下表所示。 有多种方式表示文件中的信息,若用0,1码表示字符的方法,即每个字符用唯一的一个0,1串表示。若采用定长编码表示,则需要3位表示一个字符,整个文件编码需要300,000位;若采用变长编码表示,给频率高的字符较短的编码;频率低的字符较长的编码,达到整体编码减少的目的,则整个文件编码需要(45×1+13×3+12×3+16×3+9×4+5×4)×1000=224,000位,由此可见,变长码比定长码方案好,总码长减小约25%。 前缀码:对每一个字符规定一个0,1串作为其代码,并要求任一字符的代码都不是其他字符代码的前缀。这种编码称为前缀码。编码的前缀性质可以使译码方法非常简单;例如001011101可以唯一的分解为0,0,101,1101,因而其译码为aabe。

译码过程需要方便的取出编码的前缀,因此需要表示前缀码的合适的数据结构。为此,可以用二叉树作为前缀码的数据结构:树叶表示给定字符;从树根到树叶的路径当作该字符的前缀码;代码中每一位的0或1分别作为指示某节点到左儿子或右儿子的“路标”。 从上图可以看出,表示最优前缀码的二叉树总是一棵完全二叉树,即树中任意节点都有2个儿子。图a表示定长编码方案不是最优的,其编码的二叉树不是一棵完全二叉树。在一般情况下,若C是编码字符集,表示其最优前缀码的二叉树中恰有|C|个叶子。每个叶子对应于字符集中的一个字符,该二叉树有|C|-1个内部节点。 给定编码字符集C及频率分布f,即C中任一字符c以频率f(c)在数据文件中出现。C的一个前缀码编码方案对应于一棵二叉树T。字符c在树T中的深度记为d T(c)。d T(c)也是字符c的前缀码长。则平均码长定义为:

背包问题(贪心算法)

算法分析与设计实验报告 第 4 次实验

}

附录:完整代码 #include #include #include struct node{ float value; float weight; }; float Value,curvalue=0; float Weight,curweight=0; //按价重比冒泡排序 void sort(node Node[],int M){ int i,j; node temp; for(i=0;i

贪心算法背包问题

算法设计与分析实验报告 题目:贪心算法背包问题 专业:JA V A技术xx——xxx班 学号: 姓名: 指导老师:

实验三:贪心算法背包问题 一、实验目的与要求 1、掌握背包问题的算法 2、初步掌握贪心算法 二、实验题: 问题描述:与0-1背包问题相似,给定n种物品和一个背包。物品i的重量是wi,其价值为vi,背包的容量为c。与0-1背包问题不同的是,在选择物品i装入背包时,背包问题的解决可以选择物品i的一部分,而不一定要全部装入背包,1< i < n。 三、实验代码 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class er extends JFrame { private static final long serialVersionUID = -1508220487443708466L; private static final int width = 360;// 面板的宽度 private static final int height = 300;// 面板的高度 public int M; public int[] w; public int[] p; public int length; er() { // 初始Frame参数设置 this.setTitle("贪心算法"); setDefaultCloseOperation(EXIT_ON_CLOSE); setSize(width, height); Container c = getContentPane(); c.setLayout(new BoxLayout(c, BoxLayout.Y_AXIS)); setLocation(350, 150); // 声明一些字体样式 Font topF1 = new Font("宋体", Font.BOLD, 28); Font black15 = new Font("宋体", Font.PLAIN, 20); Font bold10 = new Font("宋体", Font.BOLD, 15); // 声明工具栏及属性设置 JPanel barPanel = new JPanel(); JMenuBar topBar = new JMenuBar(); topBar.setLocation(1, 1); barPanel.add(topBar); // 面板1和顶部标签属性设置 JPanel p1 = new JPanel(); JLabel topLabel = new JLabel("背包问题");

实验二(贪心算法)

华东师范大学计算机科学技术系上机实践报告 课程名称:算法设计与分析年级:05上机实践成绩: 指导教师:柳银萍姓名:张翡翡 上机实践名称:贪心算法学号:10052130119上机实践日期:2007-4-10 上机实践编号:NO.2组号:上机实践时间:10:00-11:30 一、目的 了解熟悉掌握贪心算法实质并学会灵活运用,从而解决生活中一些实际问题。 二、内容与设计思想 1.超市的自动柜员机(POS)要找给顾客各种数值的现金,表面上看,这是一个很简单的任务,但交给机器办就不简单了。你作为一个计算机专家,要求写一个程序来对付这个“简单”的问题。 你的自动柜员机有以下的币种:100元,50元,20元,10元,5元,2元,1元。你可以假设每种钱币的数量是无限的。现在有一笔交易,需要找个客户m元,请你设计一个算法,使得找给顾客的钱币张数最少。 要求: 输入:第一行仅有一个整数n(0

c应用贪心算法求解背包问题

实验五应用贪心算法求解背包问题 学院:计算机科学与技术专业:计算机科学与技术 学号:班级:姓名: 、 实验内容: 背包问题指的是:有一个承重为W的背包和n个物品,它们各自的重量和价值分别是n ,假设W w i和v i(1 i n)w i 1i,求这些物品中最有价值的一个子集。如果每次选择某一个物品的时候,只能全部拿走,则这一问题称为离散(0-1)背包问题;如果每次可以拿走某一物品的任意一部分,则这一问题称为连续背包问题。 二、算法思想: 首先计算每种物品单位重量的价值Vi/Wi,然后,依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。若将这种物品全部装入背包后,背包内的物品总重量未超过C,则选择单位重量价值次高的物品并尽可能多地装入背包。依此策略一直地进行下去,直到背包装满为止。 三、实验过程: #in elude using n amespace std; struct goodi nfo

{ float p; // 物品效益 float w; // 物品重量 float X; // 物品该放的数量 int flag; // 物品编号 };// 物品信息结构体 void Insertionsort(goodinfo goods[],int n)// 插入排序,按pi/wi 价值收益进行排序,一般教材上按冒泡排序 { int j,i; for(j=2;j<=n;j++) { goods[0]=goods[j]; i=j-1; while (goods[0].p>goods[i].p) { } goods[i+1]=goods[0]; } }// 按物品效益,重量比值做升序排列goods[i+1]=goods[i]; i--; void bag(goodinfo goods[],float M,int n) { float cu; int i,j;

0021算法笔记——【贪心算法】贪心算法与活动安排问题

0021算法笔记——【贪心算法】贪心算法与活动安排问题 1、贪心算法 (1)原理:在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解。 (2)特性:贪心算法采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解,虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪婪法不要回溯。能够用贪心算法求解的问题一般具有两个重要特性:贪心选择性质和最优子结构性质。 1)贪心选择性质 所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局 部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素。贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。 对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。证明的大致过程为:

首先考察问题的一个整体最优解,并证明可修改这个最优解,使其以贪心选择开始。做了贪心选择后,原问题简化为规模更小的类似子问题。然后用数学归纳法证明通过每一步做贪心选择,最终可得到问题的整体最优解。其中,证明贪心选择后的问题简化为规模更小的类似子问题的关键在于利用该问题的最优子结构性质。 2)最优子结构性质 当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。 (3)贪心算法与动态规划算法的差异: 动态规划和贪心算法都是一种递推算法,均有最优子结构性质,通过局部最优解来推导全局最优解。两者之间的区别在于:贪心算法中作出的每步贪心决策都无法改变,因为贪心策略是由上一步的最优解推导下一步的最优解,而上一部之前的最优解则不作保留,贪心算法每一步的最优解一定包含上一步的最优解。动态规划算法中全局最优解中一定包含某个局部最优解,但不一定包含前一个局部最优解,因此需要记录之前的所有最优解。 (4)基本思路: 1)建立数学模型来描述问题。 2)把求解的问题分成若干个子问题。 3)对每一子问题求解,得到子问题的局部最优解。 4)把子问题的解局部最优解合成原来解问题的一个解。 2、活动安排问题

贪心算法实现背包问题算法设计与分析实验报告

算法设计与分析实验报告 实验名称贪心算法实现背包问题评分 实验日期年月日指导教师 姓名专业班级学号 一.实验要求 1. 优化问题 有n个输入,而它的解就由这n个输入满足某些事先给定的约束条件的某个子集组成,而把满足约束条件的子集称为该问题的可行解。可行解一般来说是不唯一的。那些使目标函数取极值(极大或极小)的可行解,称为最优解。 2.贪心法求优化问题 算法思想:在贪心算法中采用逐步构造最优解的方法。在每个阶段,都作出一个看上去最优的决策(在一定的标准下)。决策一旦作出,就不可再更改。作出贪心决策的依据称为贪心准则(greedy criterion)。 3.一般方法 1)根据题意,选取一种量度标准。 2)按这种量度标准对这n个输入排序 3)依次选择输入量加入部分解中。如果当前这个输入量的加入,不满足约束条件,则不把此输入加到这部分解中。 procedure GREEDY(A,n) /*贪心法一般控制流程*/ //A(1:n)包含n个输入// solutions←φ //将解向量solution初始化为空/ for i←1 to n do x←SELECT(A) if FEASIBLE(solution,x) then solutions←UNION(solution,x) endif repeat return(solution) end GREEDY 4. 实现典型的贪心算法的编程与上机实验,验证算法的时间复杂性函数。 二.实验内容 1. 编程实现背包问题贪心算法。通过具体算法理解如何通过局部最优实现全局最优,

并验证算法的时间复杂性。 2.输入5个的图的邻接矩阵,程序加入统计prim算法访问图的节点数和边数的语句。 3.将统计数与复杂性函数所计算比较次数比较,用表格列出比较结果,给出文字分析。 三.程序算法 1.背包问题的贪心算法 procedure KNAPSACK(P,W,M,X,n) //P(1:n)和W(1;n)分别含有按 P(i)/W(i)≥P(i+1)/W(i+1)排序的n件物品的效益值 和重量。M是背包的容量大小,而x(1:n)是解向量 real P(1:n),W(1:n),X(1:n),M,cu; integer i,n; X←0 //将解向量初始化为零 cu←M //cu是背包剩余容量 for i←1 to n do if W(i)>cu then exit endif X(i) ←1 cu←cu-W(i) repeat if i≤n then X(i) ←cu/ W(i) endif end GREEDY-KNAPSACK procedure prim(G,) status←“unseen” // T为空 status[1]←“tree node” // 将1放入T for each edge(1,w) do status[w]←“fringe” // 找到T的邻接点 dad[w] ←1; //w通过1与T建立联系 dist[w] ←weight(1,w) //w到T的距离 repeat while status[t]≠“tree node” do pick a fringe u with min dist[w] // 选取到T最近的节点 status[u]←“tree node” for each edge(u,w) do 修改w和T的关系 repeat repeat 2.Prim算法

贪心算法实现01背包问题

贪心算法实现01背包问题 算法思想:贪心原则为单位价值最大且重量最小,不超过背包最大承重量为约束条件。也就是说,存在单位重量价值相等的两个包,则选取重量较小的那个背包。 具体实现过程是:首先可以设置一个备份pvu类型的数组,在不破环原数据的情况下,对此备份数组按单位重量价值从大到小的排序。依次设立两个指针i,j(其中i表示当前应该参与最佳pv值的元素指针,j表示符合约束条件的指针(单位重量价值PV最大,重量最小,不超过最大承重量约束) 代码实现如下: #include using namespace std; typedef struct { int v; int w; float pv; }pvu; void sortByPv(pvu [],int ); int zeroneBags(pvu[],int,int,int * ); void print(pvu a[],int n) { for (int i=0;i

常见的贪心算法问题

4.5 哈夫曼编码 哈夫曼编码是一种被广泛应用而且非常有效的数据压缩技术,哈夫曼根据字符在文件中出现的不同频率来建立一个用0,1串表示各字符的最优编码树(称为哈夫曼树),它的设计也是贪心选择的一个典型例子。 例假设有一个包含10000个只含a,b,c,d,e,f字符的数据文件,各字符在文件中出现的频率见下4.5.1表 表 4.5.1 若采用等长编码,则需3位二进制数位来表示6个字符,这种方法要用30000位来表示整个文件。若采用变长编码,则整个文件只需 (45×1+13×3+12×3+16×3+9×4+5×4) ×100=22400 位 也就是说压缩了 (30000-22400)÷30000×100%≥25% 。实际上,这就是这个文件的最优编码方案了 4.5.1 前缀码 我们对每一字符规定一个0,1串作为其代码,并要求任一字符代码都不是其他字符代码的前缀,这样的编码简称为前缀码。在4.5.1表中的两种编码都是前缀码。由于任一字符代码都不是其他字符代码的前缀,所以译码方法非常简单。为了在译码过程中方便地取出编码的前缀,我们可以用二叉树作为前缀码的数据结构。在表示前缀码的二叉树中,树叶代表给定的字符,并将每个字符的前缀码看作是从树根到代表该字符的树叶的一条道路。代码中每一位的0或1分别作为指示某结点到左儿子或右儿子的路标。如图4-1中的两棵二叉树是表4.5.1中两种编码方案所对应的数据结构。

图 4-1 前缀码的二叉树表示 容易看出,表示最优编码方案所对应的前缀码的二叉树总是一棵完全二叉树,即树中任一结点都有2个儿子。而定长编码方案不是最优的,其编码的二叉树不是一棵完全二叉树。在一般情况下,若C是编码字符集,包含有n个字符,则表示其最优前缀码的二叉树中恰好有n个叶子。每个叶子对应于字符集中一个字符,且该二叉树恰好有n - 1个内部结点。 4.6 最小生成树 设G= (V ,E )是一个无向连通图,即一个网络。给 E 的每一条边(v, w )赋于一个权。如果G 的一个子图G ˊ是一棵包含G 的所有顶点的树,则称G ˊ为G 的生成树。生成树上各边权的总和称为该生成树的代价。在G 的所有生成树中,代价最小的生成树称为G 的最小生成树。 网络的最小生成树在实际中有着广泛的应用。在不同的背景下,边的权可以代表不同的含义,比如,两点间的距离,两点间的公路造价等等。例如,在设计通信网络时,用图的顶点表示城市,用边(v, w )的权表示建立城市v 和城市w 的之间的通信线路所需的费用,则最小生成树就给出了建立通信网络的最经济的方案。 用贪心算法设计策略可以设计出构造最小生成树的有效算法。本节中要介绍的构造最小生成树的Prim 算法和Kruskal 算法都可以看作是应用贪心算法设计策略的典型例子。 4.6.1 Prim 算法 设G= (V ,E )是一个连通带权图,V={1 ,2 ,···,n} ,二维数组W 的元素W[i][j] 表示边(i ,j )的权。构造G 的一棵最小生成树的Prim 算法的基本思想是:首先置S={1} ,

2贪心算法解决部分背包问题

2贪心算法解决部分背包问题 一、实验目的 学习掌贪心算法法思想。 二、实验内容 用贪心法解决部分背包问题。给定n种物品和一个背包。物品i的重量是Wi,其价值为pi,背包的容量为M,将物品i的一部分xi放入背包会得到pi xi的效益。应如何选择装入背包的物品,使得装入背包中物品的总价值最大?给出具体的装包方案。在选择装入背包的物品时,对每种物品i,可以整件装入背包、不装入背包或部分装入背包。但不能将物品i装入背包多次。 四、需求分析 对于给定n种物品和一背包。在容量最大值固定的情况下,要求装入的物品价值最大化。 五、基本思想: 贪婪法是解决最优化问题时的一种简单但适用范围有限的策略。总是对当前的问题作最好的选择,也就是局部寻优。最后得到整体最优。总是选择单位价值最高的物品。 六、详细设计 #include using namespace std; struct _Object//物品结构体 { int Value;//物品价值 int Weight;//物品重量 int AveValue;//物品单位价值 float Num;//物品可以放入的数量

void knaspsack(int n,float M,_Object object[]) { //n为物品个数,M为背包容量 int i; float C=M; for(i=0;iC)break;//当物品重量大于背包容量时 else//小于时 { object[i].Num=1;//物品i放入一件 C-=object[i].Weight;//背包容量减小 } } if(i<=n)//当不能放入整个物品时,选取物品一部分放入 object[i].Num=C/object[i].Weight; for(i=0;i0) cout<<"重量为: "<

贪心算法-找零问题 实验报告

实验三 课程名称:算法设计与实现实验名称:贪心算法-找零问题 实验日期:2019年5月2日仪器编号:007 班级:数媒0000班姓名:郝仁学号0000000000 实验内容 假设零钱系统的币值是{1,p,p^2,……,p^n},p>1,且每个钱币的重量都等于1,设计一个最坏情况下时间复杂度最低的算法,使得对任何钱数y,该算法得到的零钱个数最少,说明算法的主要设计思想,证明它的正确性,并给出最坏情况下的时间复杂度。 实验分析 引理1(离散数学其及应用3.1.4):若n是正整数,则用25美分、10美分、5美分和1美分等尽可能少的硬币找出的n美分零钱中,至多有2个10美分、至多有1个5美分、至多有4个1美分硬币,而不能有2个10美分和1个5美分硬币。用10美分、5美分和1美分硬币找出的零钱不能超过24美分。 证明如果有超过规定数目的各种类型的硬币,就可以用等值的数目更少的硬币来替换。注意,如果有3个10美分硬币,就可以换成1个25美分和1个5美分硬币;如果有2个5美分硬币,就可以换成1个10美分硬币;如果有5个1美分硬币,就可以换成1个5美分硬币;如果有2个10美分和1个5美分硬币,就可以换成1个25美分硬币。由于至多可以有2个10美分、1个5美分和4个1美分硬币,而不能有2个10美分和1个5美分硬币,所以当用尽可能少的硬币找n美分零钱时,24美分就是用10美分、5美分和1美分硬币能找出的最大值。 假设存在正整数n,使得有办法将25美分、10美分、5美分和1美分硬币用少于贪心算法所求出的硬币去找n美分零钱。首先注意,在这种找n美分零钱的最优方式中使用25美分硬币的个数q′,一定等于贪心算法所用25美分硬币的个数。为说明这一点,注意贪心算法使用尽可能多的25美分硬币,所以q′≤q。但是q′也不能小于q。假如q′小于q,需要在这种最优方式中用10美分、5美分和1美分硬币至少找出25美分零钱。而根据引理1,这是不可能的。由于在找零钱的这两种方式中一定有同样多的25美分硬币,所以在这两种方式中10美分、5美分和1美分硬币的总值一定相等,并且这些硬币的总值不超过24美分。10美分硬币的个数一定相等,因为贪心算法使用尽可能多的10美分硬币。而根据引理1,当使用尽可能少的硬币找零钱时,至多使用1个5分硬币和4个1分硬币,所以在找零钱的最优方式中也使用尽可能多的10美分硬币。类似地,5美分硬币的个数相等;最终,1美分的个数相等。 同上,由于1+p1+p2+p3+...pk-1=pk - 1

贪心法 求解背包问题

实验三:贪心法求解背包问题 一、实验目的与要求 1、掌握背包问题的算法 2、初步掌握贪心算法 二、实验题 问题描述:与0-1背包问题相似,给定n种物品和一个背包。物品i的重量是wi,其价值为vi,背包的容量为c。与0-1背包问题不同的是,在选择物品i装入背包时,背包问题的解决可以选择物品i的一部分,而不一定要全部装入背包,1< i < n。 三、实验代码 package xp3; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Greedy extends JFrame { private static final long serialVersionUID= -1508220487443708466L; private static final int width = 360;// 面板的宽度 private static final int height = 300;// 面板的高度 public int M; public int[] w; public int[] p; public int length; Greedy() { // 初始Frame参数设置 this.setTitle("贪心算法"); setDefaultCloseOperation(EXIT_ON_CLOSE); setSize(width, height); Container c = getContentPane(); c.setLayout(new BoxLayout(c, BoxLayout.Y_AXIS)); setLocation(350, 150); // 声明一些字体样式 Font topF1 = new Font("宋体", Font.BOLD, 28); Font black15 = new Font("宋体", Font.PLAIN, 20); Font bold10 = new Font("宋体", Font.BOLD, 15);

背包问题的贪心算法

贪心方法:总是对当前的问题作最好的选择,也就是局部寻优。最后得到整体最优。 应用:1:该问题可以通过“局部寻优”逐步过渡到“整体最优”。贪心选择性质与“动态规划”的主要差别。 2:最优子结构性质:某个问题的整体最优解包含了“子”问题的最优解。 代码如下: #include struct goodinfo { float p; //物品效益 float w; //物品重量 float X; //物品该放的数量 int flag; //物品编号 };//物品信息结构体 void Insertionsort(goodinfo goods[],int n) { int j,i; for(j=2;j<=n;j++) { goods[0]=goods[j]; i=j-1; while (goods[0].p>goods[i].p) { goods[i+1]=goods[i]; i--; } goods[i+1]=goods[0]; } }//按物品效益,重量比值做升序排列 void bag(goodinfo goods[],float M,int n) { float cu;

for(i=1;i<=n;i++) goods[i].X=0; cu=M; //背包剩余容量 for(i=1;icu)//当该物品重量大与剩余容量跳出 break; goods[i].X=1; cu=cu-goods[i].w;//确定背包新的剩余容量 } if(i<=n) goods[i].X=cu/goods[i].w;//该物品所要放的量 /*按物品编号做降序排列*/ for(j=2;j<=n;j++) { goods[0]=goods[j]; i=j-1; while (goods[0].flag

实验二 贪心算法-最少活动会场安排问题

中原工学院计算机学院 实验报告 实验项目名称实验二、最少活动会场安排问题课程名称算法设计与分析 学生姓名梁斐燕 学生学号201400824204 所在班级网络14卓越 学科专业网络工程 任课教师吴志刚 完成日期2016年月日

实验二最少活动会场安排问题 一、实验目的 1.掌握贪心算法的基本概念和两个基本要素 2.熟练掌握贪心算法解决问题的基本步骤。 3.学会利用贪心算法解决实际问题。 二、实验内容 ?问题描述: ?题目一:假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的贪心算法来进行安排,试编程实现。 ?题目二:一辆汽车加满油后,可行使n千米。旅途中有若干个加油站。 若要使沿途加油次数最少,设计一个有效算法,指出应在哪些加油站停靠加油。 ?数据输入:个人设定,由键盘输入。 ?要求: –上述题目任选一做。上机前,完成程序代码的编写 –独立完成实验及实验报告 三、实验步骤 ㈠、数据结构与核心算法的设计描述 提示:题目一:参考教材活动安排问题;有关队列操作参考数据结构。void GreedySelector(int n, int *s, int *f, int *A) { //用集合A来存储所选择的活动 A[1] = TURE; //默认从第一次活动开始执行 int j = 1; //j记录最近一次加入到A中的活动 for (int i = 2; i <= n; i++) { //f[j]为当前集合A中所有活动的最大结束时间//活动i的开始时间不早于最近加入到集合A中的j的时间f[j] if (s[i] >= f[j]) { A[i] = TURE; //当A[i]=TURE时,活动i在集合A中 j = i; } else A[i] = FALSE; } } ㈡、函数调用及主函数设计 (可用函数的调用关系图说明) 主函数 快排选择活动

贪心算法解决0-1背包问题

贪心算法--0-1背包问题 1、问题的描述 有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,4,2,1,3,它们的价值分别是3,5,6,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和? 贪心算法的思想:贪心原则为单位价值最大且重量最小,不超过背包最大承重量为约束条件。也就是说,存在单位重量价值相等的两个包,则选取重量较小的那个背包。 2、代码及注释 #include #define M 5 //定义一个node结构体,用来存放物体的重量和价值 struct node { float value;//价值 float weight;//重量 int flag; //用来判别这个物体是否装进背包 }Node[M],temp; float Value,curvalue=0;//总价值和当前价值 float Weight,curweight=0;//背包的最大承受重量和现有重量 //按性价比排序 void sort()

{ int i,j; //遍历所有物品 for(i=0;i

相关文档
最新文档