C++算法-6.贪心算法
贪心算法几个经典例子c语言

贪心算法几个经典例子c语言1. 零钱兑换问题题目描述:给定一些面额不同的硬币和一个总金额,编写一个函数来计算可以凑成总金额所需的最少的硬币个数。
如果没有任何一种硬币组合能够凑出总金额,返回 -1。
贪心策略:每次选择面额最大的硬币,直到凑出总金额或者无法再选择硬币为止。
C语言代码:int coinChange(int* coins, int coinsSize, int amount){int count = 0;for(int i = coinsSize - 1; i >= 0; i--){while(amount >= coins[i]){amount -= coins[i];count++;}}return amount == 0 ? count : -1;}2. 活动选择问题题目描述:有 n 个活动,每个活动都有一个开始时间和结束时间,选择一些活动使得它们不冲突,且能够参加的活动数最多。
贪心策略:每次选择结束时间最早的活动,直到所有活动都被选择或者无法再选择为止。
C语言代码:typedef struct{int start;int end;}Activity;int cmp(const void* a, const void* b){return ((Activity*)a)->end - ((Activity*)b)->end;}int maxActivities(Activity* activities, int n){qsort(activities, n, sizeof(Activity), cmp);int count = 1;int end = activities[0].end;for(int i = 1; i < n; i++){if(activities[i].start >= end){count++;end = activities[i].end;}}return count;}3. 跳跃游戏题目描述:给定一个非负整数数组,你最初位于数组的第一个位置。
c语言贪心算法

c语言贪心算法一、引言贪心算法是一种在每一步选择中都采取当前情况下的最佳(或最优)选择的算法,它希望通过做出局部最优选择来获得全局最优解。
在C语言中,贪心算法是一种常用的优化方法,可以应用于各种问题领域,如资源分配、背包问题、图着色等。
二、基本概念贪心算法的基本思想是,在每一步选择中,总是做出在当前看来最好的选择,期望最终能得到最优解。
贪心算法并不保证得到最优解,但在很多情况下能得到满意的结果。
在C语言中,可以使用结构体、数组等数据结构来实现贪心算法。
三、应用示例以下是一个简单的贪心算法示例,用于解决公交线路规划问题。
假设有n个公交站点,我们希望通过贪心算法来规划一条公交线路,使得线路长度最短。
```c#include<stdio.h>#include<stdlib.h>typedefstruct{intstart;//起点站编号intend;//终点站编号intdistance;//站点之间的距离}Station;//贪心算法选择站点intgreedy_route(Station*stations,intn){inti,j;intbest_distance=stations[0].distance;//初始化起点站到终点的距离为最小距离intbest_route=stations[0].start;//初始化最佳路线为起点站for(i=1;i<n;i++){//考虑所有可能的路线组合,找出当前距离最短的路线和最近的站点作为下一个站点for(j=0;j<i;j++){if(stations[j].distance+stations[i].distance<best_distance){best_distance=stations[j].distance+stations[i].distance;best_route=stations[i].end;//更新最佳路线为最近的站点}}//将当前站点加入路线中stations[i].start=best_route;//将终点站编号赋值给当前站点起始站编号}returnbest_route;//返回最终的公交线路编号}```四、总结通过以上示例,我们可以看到贪心算法在公交线路规划问题中的应用。
多机调度问题贪心算法c语言

多机调度问题贪心算法c语言一、引言多机调度问题是指将一组作业分配给多台机器,使得完成所有作业的时间最短。
在实际生产中,多机调度问题是一个常见的优化问题。
贪心算法是解决多机调度问题的一种有效方法。
本文将介绍贪心算法在C语言中的应用。
二、问题描述假设有n个作业需要分配给m台机器进行加工处理,每个作业需要的时间不同,每台机器的处理速度也不同。
现在需要设计一个算法,将这些作业分配给这些机器进行加工处理,并使得完成所有作业所需时间最短。
三、贪心算法思路贪心算法是一种基于局部最优解来构造全局最优解的思想。
对于多机调度问题,我们可以采用以下贪心策略:1. 将所有作业按照所需时间从大到小排序;2. 将第一个作业分配给第一台机器;3. 对于剩余的作业,选择当前处理时间最短的那台机器进行分配;4. 重复步骤3直到所有作业都被分配完毕。
四、C语言实现下面是C语言实现多机调度问题贪心算法的代码:#include <stdio.h>#include <stdlib.h>#define MAX_JOB 1000#define MAX_MACHINE 1000int cmp(const void *a, const void *b) {return *(int *)b - *(int *)a;}int main() {int n, m, job[MAX_JOB], machine[MAX_MACHINE] = {0}; scanf("%d%d", &n, &m);for (int i = 0; i < n; i++) {scanf("%d", &job[i]);}qsort(job, n, sizeof(int), cmp);for (int i = 0; i < n; i++) {int min_time = machine[0], min_index = 0;for (int j = 1; j < m; j++) {if (machine[j] < min_time) { min_time = machine[j]; min_index = j;}}machine[min_index] += job[i]; }int max_time = machine[0];for (int i = 1; i < m; i++) {if (machine[i] > max_time) { max_time = machine[i];}}printf("%d\n", max_time);return 0;}五、代码解析1. 宏定义和头文件引入:```#define MAX_JOB 1000#define MAX_MACHINE 1000#include <stdio.h>#include <stdlib.h>```定义了最大作业数和最大机器数,并引入了标准输入输出库和标准库。
供应链管理中配送路线规划算法的使用教程

供应链管理中配送路线规划算法的使用教程随着电子商务的兴起和物流行业的快速发展,供应链管理中的配送路线规划算法变得尤为重要。
准确的配送路线规划能够提高物流效率,降低成本,为企业节约时间和资源。
本文将介绍供应链管理中常用的一些配送路线规划算法,并详细说明它们的使用教程。
一、贪心算法贪心算法是一种简单而常用的算法,它在每一步都做出当前最优的选择,但并不保证全局最优解。
在配送路线规划中,贪心算法可以按照以下步骤进行:1.确定起点和终点:首先确定货物的起点和终点,通常是仓库和客户的地址。
2.计算距离矩阵:根据起点、终点和中间所有点的地址,计算出它们之间的距离矩阵。
3.选择最近邻居:从起点开始,选择距离最近的邻居作为下一个节点,将其添加到路径中。
4.更新路径和距离:将新节点添加到路径中,更新距离矩阵,重复步骤3,直到到达终点。
5.输出最优路径:输出路径和距离,路径即为货物的配送路线。
贪心算法的优点在于简单易懂,计算速度快。
然而,它的缺点是可能陷入局部最优解,不能保证得到最优的配送路线。
二、遗传算法遗传算法是一种模拟自然界进化过程的启发式优化算法。
在配送路线规划中,遗传算法可以按照以下步骤进行:1.初始化种群:根据货物的起点和终点,随机生成初始解作为种群。
2.计算适应度:根据候选解的质量,计算每个解的适应度值,一般可以使用总路程作为适应度函数。
3.选择操作:根据适应度值,按照一定的选择策略选出优秀的个体作为父代。
4.交叉操作:通过交叉操作生成新的子代个体,将父代的染色体片段互换,并保留优秀的基因。
5.变异操作:对子代个体进行变异操作,引入新的基因,增加算法的搜索空间。
6.更新种群:将父代和子代个体结合,形成新的种群。
7.重复步骤3-6:重复执行3-6步骤,直到满足停止准则。
8.输出最优解:输出适应度最优的个体,作为货物的配送路线。
遗传算法的优点在于能够全局搜索和优化,有较高的收敛性和适应性。
然而,它的缺点是计算复杂度较高,需要耗费更多的时间和计算资源。
贪心法

贪心法贪心法(Greedy Approach)又称贪婪法, 在对问题求解时,总是做出在当前看来是最好的选择,或者说是:总是作出在当前看来最好的选择。
也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。
当然,希望贪心算法得到的最终结果也是整体最优的。
虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。
如单源最短路经问题,最小生成树问题等。
在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。
贪心法的设计思想当一个问题具有以下的性质时可以用贪心算法求解:每一步的局部最优解,同事也说整个问题的最优解。
如果一个问题可以用贪心算法解决,那么贪心通常是解决这个问题的最好的方法。
贪婪算法一般比其他方法例如动态规划更有效。
但是贪婪算法不能总是被应用。
例如,部分背包问题可以使用贪心解决,但是不能解决0-1背包问题。
贪婪算法有时也用用来得到一个近似优化问题。
例如,旅行商问题是一个NP难问题。
贪婪选择这个问题是选择最近的并且从当前城市每一步。
这个解决方案并不总是产生最好的最优解,但可以用来得到一个近似最优解。
让我们考虑一下任务选择的贪婪算法的问题, 作为我们的第一个例子。
问题:给出n个任务和每个任务的开始和结束时间。
找出可以完成的任务的最大数量,在同一时刻只能做一个任务。
例子:下面的6个任务:start[] = {1, 3, 0, 5, 8, 5};finish[] = {2, 4, 6, 7, 9, 9};最多可完成的任务是:{0, 1, 3, 4}贪婪的选择是总是选择下一个任务的完成时间至少在剩下的任务和开始时间大于或等于以前选择任务的完成时间。
我们可以根据他们的任务完成时间,以便我们总是认为下一个任务是最小完成时间的任务。
1)按照完成时间对任务排序2)选择第一个任务排序数组元素和打印。
3) 继续以下剩余的任务排序数组。
……a)如果这一任务的开始时间大于先前选择任务的完成时间然后选择这个任务和打印。
贪心算法最短路径问题c语言代码

贪心算法最短路径问题c语言代码贪心算法最短路径问题C语言代码在计算机算法的领域中,贪心算法是一种常见的解决问题的方法。
贪心算法是一种寻找最优解的方法,就是在每个步骤中都采取最优的选择,这样每一步的最优解最终就可以得到整体的最优解。
在实际应用中,贪心算法通常被用于NP问题的解决,例如最短路径问题。
本文将介绍如何用C语言实现贪心算法解决最短路径问题。
1. 最短路径问题概述最短路径问题是一种图论问题,是指在一个有权重的有向图或无向图中,从一个指定的起点节点到达一个指定终点节点的最短路径问题。
在实际应用中,最短路径问题的应用非常广泛,例如地图导航、网络寻路、信息传递等等。
2. 贪心算法的原理贪心算法是一种自顶向下的设计方法,它主要依赖与一种贪心的选择方法。
在每个步骤中,都会选择能够最优化当前直接的步骤的答案。
因此,当遇到问题难以确定最优解时,可以使用贪心算法。
一般来说,贪心算法的优点是简单易懂,并且在特定情况下能够得到准确的答案。
3. C语言代码实现快速查找从起点到所有节点的距离是这个问题的关键,可以使用某种最短路算法,例如Dijkstra算法或贪心算法。
在这里,我们使用贪心算法解决最短路径问题。
以下是C语言代码示例:#include <stdio.h> #include <stdlib.h> #include <string.h>#define V 6int min_distance(int distance[], int visited[]) { int min_index, min_distance = INT_MAX;for (int i = 0; i < V; i++) { if (visited[i] == 0 && distance[i] <= min_distance){ min_distance = distance[i]; min_index = i; } }return min_index; }int dijkstra(int graph[V][V], int source, int destination) { int distance[V], visited[V], count; memset(distance, 0, sizeof(distance)); memset(visited, 0, sizeof(visited));for (int i = 0; i < V; i++){ distance[i] = INT_MAX; }distance[source] = 0;for (count = 0; count < V - 1; count++){ int u = min_distance(distance, visited);visited[u] = 1;for (int v = 0; v < V; v++){ if (!visited[v] && graph[u][v] &&distance[u] != INT_MAX && distance[u] + graph[u][v]< distance[v]) { distance[v] =distance[u] +graph[u][v]; } } }return distance[destination]; }int main() { int graph[V][V] = { { 0, 1, 0,0, 0, 0 }, { 0, 0, 9, 0, 0,0 }, { 2, 0, 0, 3, 0, 1 }, { 0, 0, 0, 0, 2, 0 }, { 4,6, 0, 2, 0, 0 }, { 0, 0, 0,0, 1, 0 } };int source = 0, destination = 5;int distance = dijkstra(graph, source,destination);printf("The shortest distance from node %dto %d is: %d\n", source, destination, distance);return 0; }4. 结尾在本文中,我们介绍了贪心算法解决最短路径问题的原理和C语言代码实现。
C语言版贪心算法背包问题

C语言版贪心算法背包问题#include#define N 100typedef 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<n-1;i++)< p="">{k = i;for(j=i+1;j<n;j++)< p="">if(d[k].valif(k != i){temp[i]=d[i];d[i]=d[k];d[k]=temp[i];}}}float knapsack(){int i;float x[N],sum = 0;for(i=0;ifor(i=0;i<n;i++){< p="">if(d[i].w>c) break;x[d[i].num] = 1;sum += d[i].v;c -= d[i].w;}if(i<n){< p="">x[d[i].num] = c/d[i].w;sum += x[d[i].num] * d[i].v;}return sum;}int main(){int i,j,k;float sum;printf("请输入物品总数:");scanf("%d",&n);printf("\n请输入背包容量:");scanf("%f",&c);printf("\n请输入各物品重量及价值(格式:xx,xx):");for(i=0;i<n;i++){< p=""> scanf("%f,%f",&b[i].w,&b[i].v); }for(i=0;i<="" p="">for(i=0;i<n;i++){< p="">d[i].val = b[i].v/b[i].w;d[i].v = b[i].v;d[i].w = b[i].w;}Sort();sum = knapsack();printf("%.2f\n",sum);}</n;i++){<></n;i++){<></n){<></n;i++){<></n;j++)<></n-1;i++)<>。
算法统宗中的所有题目

算法统宗中的所有题目算法是计算机科学中的重要领域,涉及到各种问题的解决方法和技巧。
以下是算法领域中的一些常见题目:1. 排序算法,如冒泡排序、插入排序、选择排序、快速排序、归并排序等。
这些算法的目标是将一组数据按照特定的顺序进行排列。
2. 查找算法,如线性查找、二分查找、哈希查找等。
这些算法用于在给定的数据集中查找特定的元素。
3. 图算法,如深度优先搜索(DFS)、广度优先搜索(BFS)、最短路径算法(如Dijkstra算法、Floyd-Warshall算法)、最小生成树算法(如Prim算法、Kruskal算法)等。
这些算法用于解决与图相关的问题,如路径搜索、连通性判断、最优路径等。
4. 动态规划,动态规划是一种将复杂问题分解成子问题来求解的方法。
常见的动态规划问题包括背包问题、最长公共子序列问题、最大子数组和问题等。
5. 字符串处理算法,如字符串匹配算法(如KMP算法、Boyer-Moore算法)、字符串编辑距离算法(如Levenshtein距离算法)等。
这些算法用于解决与字符串相关的问题,如文本搜索、模式匹配、字符串相似度计算等。
6. 贪心算法,贪心算法是一种在每一步选择中都采取当前状态下最优的选择,从而希望最终能够达到全局最优解的方法。
常见的贪心算法问题包括零钱找零问题、背包问题等。
7. 分治算法,分治算法是一种将问题分解成多个相同或相似的子问题来求解的方法。
常见的分治算法问题包括快速排序、归并排序等。
8. 图论算法,图论算法用于解决与图相关的问题,如最短路径、最小生成树、最大流等。
常见的图论算法包括Dijkstra算法、Prim算法、Kruskal算法、Ford-Fulkerson算法等。
9. 数论算法,数论算法用于解决与数学相关的问题,如素数判断、最大公约数、最小公倍数等。
常见的数论算法包括欧几里得算法、Miller-Rabin算法等。
以上只是算法领域中的一部分常见题目,还有很多其他的算法题目和应用。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
例如:n=175438 s=4 删数的过程如下: n=175438 //删掉7 15438 //删掉5 1438 //删掉4 138 //删掉8 13 //解为13 这样,删数问题就与如何寻找递减区间首字符这样一个简单的问题对应起来。 不过还要注意一个细节性的问题,就是可能会出现字符串串首有若干0的情况, 甚至整个字符串都是0的情况。按以上贪心策略编制的程序框架如下 输入n,s; for (i=1;i<=s;++i) { //一共要删除s个字符 for ( j=0;j<len-1;++j ) //从串首开始找,len是n的长度 if ( n[j]>n[j+1] ) { //找到第一个符合条件的 for ( k=j;k<len-1;++k ) //删除字符串n的第j个字符 ,后面字符往前整 n[k]=n[k+1]; break; } --len; //长度减1 } 输出n; //删去串首可能产生的无用零
问题出现在什么地方呢?我们看看图23
从图23中明显可以看出,情况a,卡车的空载率比情况b高。也就是说,上 面的分析,只考虑了货物的价值质量比,而没有考虑到卡车的运营效率,因此, 局部的最优化,不能导致全局的最优化。 因此,贪心不能简单进行,而需要全面的考虑,最后得到证明。
【例3】排队打水问题
有N个人排队到R个水龙头去打水,他们装满水桶的时间为T1,T2,…,Tn为整数且 各不相等,应如何安排他们的打水顺序才能使他们花费的时间最少? 【算法分析】 由于排队时,越靠前面的计算的次数越多,显然越小的排在越前面得出的结果越小 (可以用数学方法简单证明,这里就不再赘述),所以这道题可以用贪心法解答,基本步 骤: (1)将输入的时间按从小到大排序; (2)将排序后的时间按顺序依次放入每个水龙头的队列中; (3)统计,输出答案。 【样例输出】 【样例输入】 23 //总共花费时间 4 2 //4人打水,2个水龙头 2 6 4 5 //每个打水时间 参考程序主要框架如下: cin>>n>>r; memset(s,0,sizeof(s)); //初始化 j=0; min=0; for (i=1;i<=n;++i) //用贪心法求解 { j++; if (j==r+1) j=1; s[j]+=a[i]; min+=s[j]; } cout<<min; //输出解答
因此,利用贪心策略解题,需要解决两个问题: 首先,确定问题是否能用贪心策略求解;一般来说,适用于贪心策略 求解的问题具有以下特点: ①可通过局部的贪心选择来达到问题的全局最优解。运用贪心策略解 题,一般来说需要一步步的进行多次的贪心选择。在经过一次贪心选择之 后,原问题将变成一个相似的,但规模更小的问题,而后的每一步都是当 前看似最佳的选择,且每一个选择都仅做一次。 ②原问题的最优解包含子问题的最优解,即问题具有最优子结构的性 质。在背包问题中,第一次选择单位重量价值最大的货物,它是第一个子 问题的最优解,第二次选择剩下的货物中单位重量价值最大的货物,同样 是第二个子问题的最优解,依次类推。 ③其次,如何选择一个贪心标准?正确的贪心标准可以得到问题的最 优解,在确定采用贪心策略解决问题时,不能随意的判断贪心标准是否正 确,尤其不要被表面上看似正确的贪心标准所迷惑。在得出贪心标准之后 应给予严格的数学证明。
下面来看看0-1背包问题。 给定一个最大载重量为M的卡车和N种动物。已知第i种动物的重量为Wi, 其最大价值为Vi,设定M,Wi,Vi均为整数,编程确定一个装货方案,使得装 入卡车中的所有动物总价值最大。 【分析】对于n种动物,要么被装,要么不装,也就是说在满足卡车载重的 条件下,如何选择动物,使得动物价值最大的问题。 即确定一组x1,x2,…,xn, xi∈{0,1} f(x)=max(∑xi*vi) 其中,∑(xi*wi)≦w 从直观上来看,我们可以按照上例一样选择那些价值大,而重量轻的动物。 也就是可以按价值质量比(vi/wi)的大小来进行选择。可以看出,每做一次选 择,都是从剩下的动物中选择那些vi/wi最大的,这种局部最优的选择是否能满 足全局最优呢?我们来看看一个简单的例子: 设n=3,卡车最大载重量是100,三种动物a、b、c的重量分别是40,50, 70,其对应的总价值分别是80、100、150。 情况a:按照上述思路,三种动物的vi/wi分别为2,2,2.14。显然,我们首先 选择动物c,得到价值150,然后任意选择a或b,由于卡车最大载重为100,因 此卡车不能装载其他动物。 情况b:不按上述约束条件,直接选择a和b。可以得到价值80+100=180, 卡车装载的重量为40+50=90。没有超过卡车的实际载重,因此也是一种可行 解,显然,这种解比上一种解要优化。
【算法分析】 如果你想到把每堆牌的张数减去平均张数,题目就变成移动正数,加 到负数中,使大家都变成0,那就意味着成功了一半!拿例题来说,平均张 数为10,原张数9,8,17,6,变为-1,-2,7,-4,其中没有为0的数,我 们从左边出发:要使第1堆的牌数-1变为0,只须将-1张牌移到它的右边 (第2堆)-2中;结果是-1变为0,-2变为-3,各堆牌张数变为0,-3,7,-4; 同理:要使第2堆变为0,只需将-3移到它的右边(第3堆)中去,各堆牌张 数变为0,0,4,-4;要使第3堆变为0,只需将第3堆中的4移到它的右边 (第4堆)中去,结果为0,0,0,0,完成任务。每移动1次牌,步数加1。 也许你要问,负数张牌怎么移,不违反题意吗?其实从第i堆移动-m张牌到 第i+1堆,等价于从第i+1堆移动m张牌到第i堆,步数是一样的。 如果张数中本来就有为0的,怎么办呢?如0,-1,-5,6,还是从左算 起(从右算起也完全一样),第1堆是0,无需移牌,余下与上相同;再比 如-1,-2,3,10,-4,-6,从左算起,第1次移动的结果为0,-3,3,10, -4,-6;第2次移动的结果为0,0,0,10,-4,-6,现在第3堆已经变为0 了,可节省1步,余下继续。
第六章 贪心算法
若在求解一个问题时,能根据每次所得到的局部最优解,推导出全局最 优或最优目标。那么,我们可以根据这个策略,每次得到局部最优解答,逐 步而推导出问题,这种策略称为贪心法。下面我们看一些简单例题。
【例1】在N行M列的正整数矩阵中,要求从每行中选出1个数,使得选出的总共N个 数的和最大。 【算法分析】 要使总和最大,则每个数要尽可能大,自然应该选每行中最大的那个数。因此, 我们设计出如下算法: 读入N, M,矩阵数据; Total = 0; for (int l= 1; l<= N; ++l) { //对N行进行选择 选择第I行最大的数,记为K; Total +=K; } 输出最大总和Total; 从上例中我们可以看出,和递推法相仿,贪心法也是从问题的某一个初始解出发, 向给定的目标递推。但不同的是,推进的每一步不是依据某一固定的递推式,而是做 一个局部的最优选择,即贪心选择(在例中,这种贪心选择表现为选择一行中的最大 整数),这样,不断的将问题归纳为若干相似的子问题,最终产生出一个全局最优解。 特别注意的是,局部贪心的选择是否可以得出全局最优是能否采用贪心法的关键 所在。对于能否使用贪心策略,应从理论上予以证明。下面我们看看另一个问题。
【例5】删数问题(NOI94) 输入一个高精度的正整数N,去掉其中任意S个数字后剩下的数字按原左右 次序组成一个新的正整数。编程对给定的N和S,寻找一种方案使得剩下的数字 组成的新数最小。 输出新的正整数。(N不超过240位)输入数据均不需判错。 【输入】 n s 【输出】 最后剩下的最小数。 【样例输入】 175438 4 【样例输出】 13 【算法分析】 由于正整数n的有效数位为240位,所以很自然地采用字符串类型存贮n。 那么如何决定哪s位被删除呢?是不是最大的s个数字呢?显然不是,大家很容 易举出一些反例。为了尽可能逼近目标,我们选取的贪心策略为:每一步总是 选择一个使剩下的数最小的数字删去,即按高位到低位的顺序搜索,若各位数 字递增,则删除最后一个数字;否则删除第一个递减区间的首字符,这样删一 位便形成了一个新数字串。然后回到串首,按上述规则再删下一个数字。重复 以上过程s次为止,剩下的数字串便是问题的解了。
问题初始化; //读入数据 按Vi从大到小将商品排序; i=1; do { if (m==0) break; //如果卡车满载则跳出循环 m=m-w[i]; if (m>=0) //将第i种商品全部装入卡车 else 将(m+w[i]) 重量的物品i装入卡车; i=i+1; //选择下一种商品 }while (m>0&&i<=n); 在解决上述问题的过程中,首先根据题设条件,找到了贪心选择标准(Vi), 并依据这个标准直接逐步去求最优解,这种解题策略被称为贪心法。
【例4】均分纸牌(NOIP2002) 有 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) 【输出格式】 所有堆均达到相等时的最少移动次数。 【样例输入】Playcard.in 4 9 8 17 6 【样例输出】Playcard.out 3