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

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

实验三

课程名称:算法设计与实现实验名称:贪心算法-找零问题

实验日期: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

假若最优解不含币值j

p 的钱币,即112210--+?+++=j j p x p x p x x y 那么存在{}1,1,0,-?∈≥j i p x i ,,如果不是,则

11)(1(12112210-=+?+++-≤+?+++=---j j j j p p p p p p x p x p x x y

与j p ≥y 矛盾,不妨设p x i ≥,那么用1个币值为1+i p 的钱币替换p 个币值为j

p 的钱币,总钱币数将减少1-p ,与这个解为最优解矛盾。下面证明最优解签好含有??

j p /y 个币值j p 的钱币。设钱数为y 时最优解是()y F j ,则

()()

()?????<≥+-=-j j j j j j p y y F p y p y F y F 11 设()j j p tp y <+=δδ其中??j

p y t /= 通过对t 的归纳不难证明()()δ1

j -+=j F t y F ,即最优解中含有??

j p y /个币值j p 的钱币。 上诉算法在最坏情况下的时间复杂度是()()}log ,m in{y n O n W =.

实验源代码

// 找零ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 //数媒1703班-1191170329-唐思成

// coin.cpp : 定义控制台应用程序的入口点。

//

#include "pch.h"

#include

#include

using namespace std;

//money 需要找零的钱

//coin 可用的硬币的种类

//n 硬币种类的数量

void ZhaoLing(int money , int *coin , int n ){

int *coinNum = new int [money + 1]();//存储1...money 找零最少需要的硬币的个数

int *coinValue = new int [money + 1]();//最后加入的硬币,方便后面输出是哪几个硬币 coinNum[0] = 0;

for (int i = 1; i <= money; i++)

{

int minNum = i;//i面值钱,需要最少硬币个数

int usedMoney = 0;//这次找零,在原来的基础上需要的硬币

for (int j = 0; j < n; j++)

{

if (i >= coin[j])//找零的钱大于这个硬币的面值

{

if (coinNum[i - coin[j]] + 1 <= minNum && (i == coin[j] || coinValue[i - coin[j]] != 0))//所需硬币个数减少了

{

minNum = coinNum[i - coin[j]] + 1;//更新

usedMoney = coin[j];//更新

}

}

}

coinNum[i] = minNum;

coinValue[i] = usedMoney;

}

//输出结果

if (coinValue[money] == 0)

cout <<"找不开零钱"<< endl;

else

{

cout <<"需要最少硬币个数为:"<< coinNum[money] << endl;

cout <<"硬币分别为:";

while (money > 0)

{

cout << coinValue[money] <<",";

money -= coinValue[money];

}

cout << endl;

}

delete[]coinNum;

delete[]coinValue;

}

int main(){

int Money;

int n,i,p;

cout <<"请输入需要找零的钱的值"<< endl;

cin >> Money;

cout <<"请输入硬币种类的数量"<< endl;

cin >> n;

int*coin = (int*)malloc(n * sizeof(int));//定义动态长度的数组

cout <<"请输入零钱的底数"<< endl;

while(1) {

cin >> p;

if (p > 0) {

break;

}

else {

cout <<"输入的数小于零,请重新输入"<< endl;

}

}

for (i = 0; i < n; i++) {

coin[i] = pow(p, i);

}

cout <<"找零系统中的零钱种类为:"<< endl;

for (i = 0; i < n; i++) {

cout << coin[i] <<",";

}

cout << endl;

ZhaoLing(Money, coin, n);

system("pause");

return 0;

}

实验结果

贪心算法经典例题

贪心算法经典例题 发布日期: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

算法设计与分析实验报告贪心算法

算法设计与分析实验报告 贪心算法 班级:2013156 学号:201315614 姓名:张春阳哈夫曼编码 代码 #include float small1,small2; int flag1,flag2,count; typedefstructHuffmanTree { float weight; intlchild,rchild,parent; }huffman; huffmanhuffmantree[100]; void CreatHuffmanTree(intn,int m) { inti; void select(); printf("请输入%d个节点的权值:",n); for(i=0;i

printf("\n"); for(i=0;i

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

《算法分析与设计》 课程实验 专业年级:信息与计算科学 学生学号: 学生姓名: 实验题目:用贪婪法求解背包问题 指导老师: 实验时间: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.熟悉VC环境,加强编程、调试的练习; 3.用C语言编写函数,实现循环链表的建立、插入、删除、取数据等基本操作; 4.理论知识与实际问题相结合,利用上述基本操作实现约瑟夫环。 二、实验内容 1、采用单向环表实现约瑟夫环。 请按以下要求编程实现: ①从键盘输入整数m,通过create函数生成一个具有m个结点的单向环表。环表中的 结点编号依次为1,2,……,m。 ②从键盘输入整数s(1<=s<=m)和n,从环表的第s个结点开始计数为1,当计数到 第n个结点时,输出该第n结点对应的编号,将该结点从环表中消除,从输出结点 的下一个结点开始重新计数到n,这样,不断进行计数,不断进行输出,直到输出 了这个环表的全部结点为止。 三、程序设计 1、概要设计 为实现上述程序功能,应用单向环表寄存编号,为此需要建立一个抽象数据类型:单向环表。 (1)、单向环表的抽象数据类型定义为: ADT Joseph{ 数据对象:D={ai|ai∈ElemSet,i=1,2,3……,n,n≥0} 数据关系:R1={ |ai∈D,i=1,2,……,n} 基本操作: create(&L,n) 操作结果:构造一个有n个结点的单向环表L。 show(L) 初始条件:单向环表L已存在。 操作结果:按顺序在屏幕上输出L的数据元素。 Josephf( L,m,s,n) 初始条件:单向环表L已存在, s>0,n>0,s

贪心算法0-1背包问题(算法实验代码)

实验三、0-1背包问题(贪心算法) 实验代码: #include int max(int a,int b) { if(a>b) return a; else return b; } void Knapsack(int *v,int *w,int *x,int c,int n, int m[8][100]) { int i,j; for(j=0;j=1;i--) { for(j=w[i];j<=c;j++) m[i][j]=max(m[i+1][j],m[i+1][j-w[i]]+v[i]); } for(i=1;i

printf("物品总数为:7\n"); printf("物品重量和价值分别为:\n"); printf("\n重量价值\n"); for (i=1;i<=n;i++) printf("%d %d \n",w[i],v[i]); int m=15; int array[8][100]={0}; Knapsack(v,w,x,m,7,array); printf("背包能装的最大价值为: %d\n",array[1][m]); printf("贪心算法的解为: "); for(i=1;i<=n;i++) { if(i==1) printf("%d",x[i]); else printf(" %d",x[i]); } printf("\n"); return 0; } 测试截图为:

贪心算法 找零钱问题

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

实验三:贪心算法运用练习 一、实验目的 本次实验是针对贪心算法运用的算法设计及应用练习,旨在加深学生对该部分知识点的理解,提高学生运用该部分知识解决问题的能力。 二、实验步骤与要求 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;

算法设计与实验报告讲解

算法设计与分析实验报告 学院:信息学院 专业:物联网1101 姓名:黄振亮 学号:20113379 2013年11月

目录 作业1 0-1背包问题的动态规划算法 (7) 1.1算法应用背景 (3) 1.2算法原理 (3) 1.3算法描述 (4) 1.4程序实现及程序截图 (4) 1.4.1程序源码 (4) 1.4.2程序截图 (5) 1.5学习或程序调试心得 (6) 作业2 0-1背包问题的回溯算法 (7) 2.1算法应用背景 (3) 2.2算法原理 (3) 2.3算法描述 (4) 2.4程序实现及程序截图 (4) 2.4.1程序源码 (4) 2.4.2程序截图 (5) 2.5学习或程序调试心得 (6) 作业3循环赛日程表的分治算法 (7) 3.1算法应用背景 (3) 3.2算法原理 (3) 3.3算法描述 (4) 3.4程序实现及程序截图 (4)

3.4.1程序源码 (4) 3.4.2程序截图 (5) 3.5学习或程序调试心得 (6) 作业4活动安排的贪心算法 (7) 4.1算法应用背景 (3) 4.2算法原理 (3) 4.3算法描述 (4) 4.4程序实现及程序截图 (4) 4.4.1程序源码 (4) 4.4.2程序截图 (5) 4.5学习或程序调试心得 (6)

作业1 0-1背包问题的动态规划算法 1.1算法应用背景 从计算复杂性来看,背包问题是一个NP难解问题。半个世纪以来,该问题一直是算法与复杂性研究的热点之一。另外,背包问题在信息加密、预算控制、项目选择、材料切割、货物装载、网络信息安全等应用中具有重要的价值。如果能够解决这个问题那么则具有很高的经济价值和决策价值,在上述领域可以获得最大的价值。本文从动态规划角度给出一种解决背包问题的算法。 1.2算法原理 1.2.1、问题描述: 给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问:应如何选择装入背包的物品,使得装入背包中物品的总价值最大? 形式化描述:给定c >0, wi >0, vi >0 , 1≤i≤n.要求找一n元向量(x1,x2,…,xn,), xi ∈{0,1}, ?∑ wi xi≤c,且∑ vi xi达最大.即一个特殊的整数规划问题。 1.2.2、最优性原理: 设(y1,y2,…,yn)是 (3.4.1)的一个最优解.则(y2,…,yn)是下面相应子问题的一个最优解: 证明:使用反证法。若不然,设(z2,z3,…,zn)是上述子问题的一个最优解,而(y2,y3,…,yn)不是它的最优解。显然有 ∑vizi > ∑viyi (i=2,…,n) 且 w1y1+ ∑wizi<= c 因此 v1y1+ ∑vizi (i=2,…,n) > ∑ viyi, (i=1,…,n) 说明(y1,z2, z3,…,zn)是(3.4.1)0-1背包问题的一个更优解,导出(y1,y2,…,yn)不是背包问题的最优解,矛盾。 1.2.3、递推关系:

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的前缀码长。则平均码长定义为:

银行家算法设计实验报告

银行家算法设计实验报告

银行家算法设计实验报告 一.题目分析 1.银行家算法: 我们可以把操作系统看做是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求资源相当于客户向银行家贷款。操作系统按银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程尚需求的资源量,若是系统现存的资源可以满足它尚需求的资源量,则按当前的申请量来分配资源,否则就推迟分配。 当进程在执行中继续申请资源时,先测试该进程申请的资源量是否超过了它尚需的资源量。若超过则拒绝分配,若没有超过则再测试系统尚存的资源是否满足该进程尚需的资源量,若满足即可按当前的申请量来分配,若不满足亦推迟分配。 2.基本要求: (1)可以输入某系统的资源以及T0时刻进程对资源的占用及需求情况的表项,以及T0时刻系统的可利用资源数。 (2)对T0时刻的进行安全性检测,即检测在T0时刻该状态是否安全。

(3)进程申请资源,用银行家算法对其进行检测,分为以下三种情况: A. 所申请的资源大于其所需资源,提示分配不合理不予分配并返回 B. 所申请的资源未大于其所需资源, 但大于系统此时的可利用资源,提 示分配不合理不予分配并返回。 C. 所申请的资源未大于其所需资源, 亦未大于系统此时的可利用资源,预 分配并进行安全性检查: a. 预分配后系统是安全的,将该进 程所申请的资源予以实际分配并 打印后返回。 b. 与分配后系统进入不安全状态,提示系统不安全并返回。 (4)对输入进行检查,即若输入不符合条件,应当报错并返回重新输入。 3.目的: 根据设计题目的要求,充分地分析和理解题 目,叙述系统的要求,明确程序要求实现的功能以及限制条件。 明白自己需要用代码实现的功能,清楚编写每部分代码的目的,做到有的放矢,有条理不遗漏的用代码实现银行家算法。

背包问题(贪心算法)

算法分析与设计实验报告 第 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

南京邮电大学算法设计实验报告——动态规划法

实验报告 (2009/2010学年第一学期) 课程名称算法分析与设计A 实验名称动态规划法 实验时间2009 年11 月20 日指导单位计算机学院软件工程系 指导教师张怡婷 学生姓名丁力琪班级学号B07030907 学院(系) 计算机学院专业软件工程

实验报告 实验名称动态规划法指导教师张怡婷实验类型验证实验学时2×2实验时间2009-11-20一、实验目的和任务 目的:加深对动态规划法的算法原理及实现过程的理解,学习用动态规划法解决实际应用中的最长公共子序列问题。 任务:用动态规划法实现求两序列的最长公共子序列,其比较结果可用于基因比较、文章比较等多个领域。 要求:掌握动态规划法的思想,及动态规划法在实际中的应用;分析最长公共子序列的问题特征,选择算法策略并设计具体算法,编程实现两输入序列的比较,并输出它们的最长公共子序列。 二、实验环境(实验设备) 硬件:计算机 软件:Visual C++

三、实验原理及内容(包括操作过程、结果分析等) 1、最长公共子序列(LCS)问题是:给定两个字符序列X={x1,x2,……,x m}和Y={y1,y2,……,y n},要求找出X和Y的一个最长公共子序列。 例如:X={a,b,c,b,d,a,b},Y={b,d,c,a,b,a}。它们的最长公共子序列LSC={b,c,d,a}。 通过“穷举法”列出所有X的所有子序列,检查其是否为Y的子序列并记录最长公共子序列并记录最长公共子序列的长度这种方法,求解时间为指数级别的,因此不可取。 2、分析LCS问题特征可知,如果Z={z1,z2,……,z k}为它们的最长公共子序列,则它们一定具有以下性质: (1)若x m=y n,则z k=x m=y n,且Z k-1是X m-1和Y n-1的最长公共子序列; (2)若x m≠y n且x m≠z k,则Z是X m-1和Y的最长公共子序列; (3)若x m≠y n且z k≠y n,则Z是X和Y的最长公共子序列。 这样就将求X和Y的最长公共子序列问题,分解为求解较小规模的问题: 若x m=y m,则进一步分解为求解两个(前缀)子字符序列X m-1和Y n-1的最长公共子序列问题; 如果x m≠y n,则原问题转化为求解两个子问题,即找出X m-1和Y的最长公共子序列与找出X 和Y n-1的最长公共子序列,取两者中较长者作为X和Y的最长公共子序列。 由此可见,两个序列的最长公共子序列包含了这两个序列的前缀的最长公共子序列,具有最优子结构性质。 3、令c[i][j]保存字符序列X i={x1,x2,……,x i}和Y j={y1,y2,……,y j}的最长公共子序列的长度,由上述分析可得如下递推式: 0 i=0或j=0 c[i][j]= c[i-1][j-1]+1 i,j>0且x i=y j max{c[i][j-1],c[i-1][j]} i,j>0且x i≠y j 由此可见,最长公共子序列的求解具有重叠子问题性质,如果采用递归算法实现,会得到一个指数时间算法,因此需要采用动态规划法自底向上求解,并保存子问题的解,这样可以避免重复计算子问题,在多项式时间内完成计算。 4、为了能由最优解值进一步得到最优解(即最长公共子序列),还需要一个二维数组s[][],数组中的元素s[i][j]记录c[i][j]的值是由三个子问题c[i-1][j-1]+1,c[i][j-1]和c[i-1][j]中的哪一个计算得到,从而可以得到最优解的当前解分量(即最长公共子序列中的当前字符),最终构造出最长公共子序列自身。

贪心算法背包问题

算法设计与分析实验报告 题目:贪心算法背包问题 专业: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

算法与设计实验报告

算法与分析实验报告软件工程专业 安徽工业大学 指导老师:许精明

实验内容 1:杨辉三角 2:背包问题 3:汉诺塔问题 一:实验目的 1:掌握动态规划算法的基本思想,学会用其解决实际问题。 2:通过几个基本的实验,提高算法分析与设计能力,提高动手操作能力和培养良好的编程习惯。 二:实验内容 1:杨辉三角 2:背包问题 3:汉诺塔问题 实验一:杨辉三角

问题分析: ①每行数字左右对称,由1开始逐渐变大,然后变小,回到1。 ②第n行数之和为2^n。 ③下一行每个数字等于上一行的左右两个数字之和。 算法设计及相关源代码: public void yanghui(int n) { int[] a = new int[n]; if(n==1){ System.out.println(1); }else if(n==2) { System.out.print(1 + " " +1); }else{ a[1]=1; System.out.println(a[1]); a[2]=1;

System.out.println(a[1]+" "+a[2]); for(int i=3;i<=n;i++){ a[1]=a[i]=1; for(int j=i-1;j>1;j--){ a[j]=a[j]+a[j-1]; } for(int j=1;j<=i;j++){ System.out.print(a[j]+" "); } System.out.println(); } } } 实验结果:n=10 实验二:0-1背包问题 问题分析::令V(i,j)表示在前i(1<=i<=n)个物品中能够装入容量为就 j(1<=j<=C)的背包中的物品的最大价值,则可以得到如下的动态规划函数: (1) V(i,0)=V(0,j)=0 (2) V(i,j)=V(i-1,j) j

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;

贪心算法详解分析

贪心算法详解 贪心算法思想: 顾名思义,贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。当然,希望贪心算法得到的最终结果也是整体最优的。虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。如单源最短路经问题,最小生成树问题等。在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。 贪心算法的基本要素: 1.贪心选择性质。所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。 动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。 对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。 2. 当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的 最优子结构性质是该问题可用动态规划算法或贪心算法求解的关键特征。 贪心算法的基本思路: 从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到算法中的某一步不能再继续前进时,算法停止。 该算法存在问题: 1. 不能保证求得的最后解是最佳的; 2. 不能用来求最大或最小解问题; 3. 只能求满足某些约束条件的可行解的范围。 实现该算法的过程: 从问题的某一初始解出发; while 能朝给定总目标前进一步do 求出可行解的一个解元素; 由所有解元素组合成问题的一个可行解; 用背包问题来介绍贪心算法: 背包问题:有一个背包,背包容量是M=150。有7个物品,物品可以分割成任意大小。要 求尽可能让装入背包中的物品总价值最大,但不能超过总容量。

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

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

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

算法设计实验报告(川大陈瑜)

《算法设计》课程报告 课序号: 01 学号: 2012141461134 姓名:刘佳玉 任课教师:陈瑜 评阅成绩: 评阅意见: 提交报告时间:2014年 6 月 16 日

贪心算法 1、问题描述 (这是我在soj上找的一道题,以前没做出来,现在用贪心的思想做出来了) 约翰要去钓鱼。他有h小时可用(1≤h≤16),在这个地区有n个湖泊(2≤n≤25),所有的湖泊沿着一条单行道可到达。约翰从湖泊1开始,他可以在任何湖泊结束。他只能从一个湖,到下一个,但他没有必要停在任何湖除非他想停。对于每个i = 1,……,n-1,ti 表示从湖i到湖i+1的5分钟的时间间隔(0 < ti < = 192)。例如,t3 = 4意味着它从湖3湖4需要20分钟的时间。 为了帮助他们规划自己的钓鱼旅行,约翰已经收集了一些关于湖泊信息。对于每个湖泊的i,能钓到的鱼在最初的5分钟的数量,用fi表示(fi > = 0),是已知的。每钓5分钟的鱼,能钓到的鱼在接下来的5分钟的间隔降低一个恒定的数di(di>=0)。如果能钓到的鱼在一个时间区的数量小于或等于di,将不会有更多的鱼留在湖里在下一个时间间隔。为了简化规划,约翰认为没有人会在影响他期待钓到的鱼的数量的湖里钓鱼。 写一个程序来帮助约翰计划他的最大化期望钓到的鱼的数量的钓鱼之旅。在每个湖花费的时间数必须是5的倍数。 这个问题包含多个测试案例! 一个多输入的第一行是一个整数N,然后一个空白行后的N个输入块。每个输入块由问题描述中的格式表示的。每个输入块之间有一个空行。 输出格式包含N个输出块。输出块之间要有一个空白行。 输入 在输入中,会给你一个案例输入的数量。每一种情况下,以n开始,其次是h,接下来有一行n个整数指定fi(1 < =i< = n),然后有一行n个整数di(1≤i<=n),最后,有一行n - 1的整数ti(1≤i<=n-1)。输入在n=0的情况下终止。 输出

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

算法设计与分析实验报告 实验名称贪心算法实现背包问题评分 实验日期年月日指导教师 姓名专业班级学号 一.实验要求 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算法

相关文档
最新文档