贪心算法的几个应用

贪心算法具有2个性质:

1、贪心选择性质:只在当前状态下做最优选择,即局部最优选择,再自顶向下,去解做出这个选择后产生的相应子问题。每做一次选择,问题就转化为规模更小的子问题。对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步做出的选择最终导致问题的整体最优解。

2、最优子结构性质:问题的最优解包含子问题的最优解。

 

贪心算法的几个应用:

哈夫曼编码:二叉树&最小优先级队列

dijktra:原始集合、选中节点集合、dist

最小生成树:prim:原始集合、选中几点集合、closestlowcost

最小生成树:kruskul:并查集&最小优先级队列

 

具体代码: 

dijktra:

设邻接矩阵:a[][],有n个节点。

1.初始化:dist[i] = a[v][i],原始集合中只有v

2.dist的最小值,加入原始集合中,更新其他dist,更新n-1

具体代码如下:

/*

5

0 10 10000 30 100

10000 0 50 10000 10000

10000 10000 0 10000 10

10000 10000 20 0 60

10000 10000 10000 10000 0

 

1

*/

 

#include<stdio.h>

#include<stdlib.h>

 

#define NUM 10

#define MAX_VALUE 10000

 

int dist[NUM];

int s[NUM];

int pre[NUM];

 

void  dijkstra(int v,int a[NUM][NUM], int n){

      //初始化

      int i=1,j=1;

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

           dist[i] = a[v][i];

           s[i] = false;

           if(a[v][i] == MAX_VALUE){

                 pre[i] = 0;

           }else{

                 pre[i] = v;

           }

      }    

     

      s[v] = true;

      dist[v] = 0;

     

      //更新n-1次

      int min = 0,tmp=v;

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

            //找最小的dist

            min = MAX_VALUE;

            for(j=1; j<=n; j++){

                     if(!s[j] && min>dist[j]){

                              min = dist[j];

                              tmp = j;

                     }

            }

            s[tmp] = true;   //tmp的初始值是v,不能为0或者随意

     

            //用最小的dist更新已有的dist

            for(j=1; j<=n; j++){

                     if(!s[j] && a[tmp][j] < MAX_VALUE && (dist[tmp]+a[tmp][j] < dist[j])){

                              dist[j] = dist[tmp]+a[tmp][j];

                              pre[j] = tmp;

                     }

            }

      }

}

 

int main(){

    int i=1,j=1,v,n,a[NUM][NUM];

   

    //输入邻接矩阵

    scanf("%d",&n);

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

       for(j=1; j<=n; j++){

           scanf("%d",&a[i][j]);

       }

    }

   

    //输入起始节点

    scanf("%d",&v);

   

    //计算dijkstra

    dijkstra(v,a,n);

   

    //打印源点到各点的最短距离

    int tmp = 0;

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

           printf("从%d到%d的距离是%d\n",v,i,dist[i]);

           tmp = i;

           printf("从%d到%d的最短路经过:");

           while(pre[tmp]>0 && pre[tmp] != v){

               printf("%d ",pre[tmp]);

               tmp = pre[tmp];

           }

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

    }

 

    system("pause");

    return 0;

}

 

时间复杂度分析:使用邻接矩阵,o(n*n)

 

最小生成树:prim

/*
6
0 6 1 5 10000 10000
6 0 5 10000 3 10000
1 5 0 5 6 1
5 10000 5 0 10000 2
10000 3 6 10000 0 6
10000 10000 1 2 6 0

*/

#include<stdio.h>
#include<stdlib.h>

#define NUM 10
#define MAX_VALUE 10000
 
int closest[NUM];  //closest[j]记录j和S中的邻接节点中距离最近的节点 
int lowcost[NUM];  //lowcost[j]记录j和S中最近邻接点的距离 
int s[NUM];        //s[j] = true,标记j在S中

int prim(int a[NUM][NUM],int n){
    //初始化
    int i,j,sum=0;
    for(i=1; i<=n; i++){
             closest[i] = 1;
             lowcost[i] = a[i][1];
             s[i] = false;
    }
    s[1] = true;

    for(j=1; j<n; j++){
        //寻找离S中节点最近的节点及距离
        int min = MAX_VALUE,v=1;
        for(i=1; i<=n; i++){
             if(!s[i] && min > lowcost[i]){
                      min = lowcost[i];
                      v = i;
             }
        }
        s[v] = true;
        sum += lowcost[v];
    
        //每添加一个新的节点到S,比较节点i和S中以前节点的最短距离 和 i和新增节点的最短距离,更新closest和c
        for(i=1; i<=n; i++){
             if(!s[i] && a[i][v] < lowcost[i]){
                      lowcost[i] = a[i][v];
             }
        }            
    }     
    
    return sum;                   
    
}

int main(){
    int i=1,j=1,n,a[NUM][NUM];
    
    //输入邻接矩阵 
    scanf("%d",&n);
    for(i=1; i<=n; i++){
       for(j=1; j<=n; j++){
           scanf("%d",&a[i][j]);
       }
    }
    
    printf("%d",prim(a,n));
    
    system("pause");
    return 0;

时间复杂度是:o(n*n)

说明:最小生成树primdijkstra相似,dijkstra保存了各点和源点的最近距离(dist)prim保存了各点和S中节点的最近邻接点及和最近邻接点的距离(closest, lowcost)。程序的书写过程相似,先初始化,再找最小的距离,再更新数组。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/435858.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#类和接口、虚方法和抽象方法及值类型和引用类型的区别

1.C#类和接口的区别 接口是负责功能的定义&#xff0c;项目中通过接口来规范类&#xff0c;操作类以及抽象类的概念&#xff01; 而类是负责功能的具体实现&#xff01; 在类中也有抽象类的定义&#xff0c;抽象类与接口的区别在于&#xff1a; 抽象类是一个不完全的类&#xf…

【转】DICOM医学图像读取涉及到的医学坐标体系

转&#xff1a;https://blog.csdn.net/sunyao_123/article/details/78975816 确定患者的位置和躺的方向主要有3个标签: (0018, 5100) Patient Position CS: ‘HFS’ (0020, 0032) Image Position (Patient) DS: [‘-167’, ‘-92’, ‘-28.5’] (0020, 0037) Image Orientatio…

学习 SQL 语句 - Select(4): 排序

Order By Asc|Desc本例效果图:代码文件:unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls, ExtCtrls, Grids, DBGrids, DB, ADODB;typeTForm1 class(TForm)DBGrid1: TDBGrid;DataSource1: TDataSource;…

二叉树总结一

二叉树的知识点1&#xff1a; 二叉树存储结构 前序建立二叉树 前序遍历、中序遍历、后序遍历&#xff08;递归、非递归&#xff09; 二叉树节点总数 二叉树叶子节点数 二叉树深度 遍历二叉树第i层节点 分层遍历二叉树&#xff08;递归、非递归&#xff09; 求二叉树中节点的最大…

【转】Ubuntu 16.04 远程桌面

转自&#xff1a;实现Windows直接远程访问Ubuntu 18.04&#xff08;旧版本也支持,无需安装第三方桌面,直接使用自带远程工具&#xff09; - 法号阿兴 - 博客园 一、设置Ubuntu 16.04 允许进行远程控制 首先&#xff0c;我们先设置Ubuntu的远程控制&#xff0c;将其设置为允许被…

GridView应用整理

2009年5月31日下午 21:58:38 获取GridView中RowCommand的当前选中行索引 <asp:GridView ID"BookGridView" runat"server"><Columns><asp:BoundField DataField"id" HeaderText"图书编号" /><asp:BoundField Data…

【转】VNC不同软件之间的联系与区别

转自&#xff1a;http://www.52iot.net/book/net/76.mhtml 如果不是经常远程不建议使用VNC&#xff0c;毕竟比较耗资源 不建议使用vnc&#xff0c; 如果只是使用文件服务&#xff0c;可以通过ssh协议的客户端访问过去操作。 现在gnome&#xff0c;kde, unity都是内置的&#x…

二叉树总结二

二叉树基本知识点2&#xff1a; 二叉树的非递归后序遍历 前序遍历是&#xff1a;根、左、右&#xff0c;后序遍历是&#xff1a;左、右、根&#xff0c;观察发现&#xff1a;前序和后序刚好遍历顺序相反。由于非递归后序遍历需要保存根节点及第几次访问&#xff0c;比较麻烦。可…

【转】Ubuntu下使用sysv-rc-conf管理服务

转自&#xff1a;https://www.linuxidc.com/Linux/2016-11/136834.htm sysv-rc-conf简介 sysv-rc-conf是一个强大的服务管理程序&#xff0c;群众的意见是sysv-rc-conf比chkconfig、rcconf好用。 背景知识 Ubuntu运行级别 Linux 系统任何时候都运行在一个指定的运行级上&…

几个常用SQL2000语句

排名语句select *,(select count(1) 1 from tPlanApply where applyquantity> a.applyquantity ) as 名次 from tPlanApply a order by 名次 替换语句 SQL code update tbset 字段replace(字段,替换后字符串,替换前字符串) 转载于:https://www.cnblogs.com/delphix/archiv…

WINCE6.0支持Multiple XIP

1. Multiple XIP support XIP(eXecute-In-Place)是本地执行&#xff0c;允许在ROM芯片内执行XIP区域(region)的应用代码&#xff0c;而不必再把代码读取到RAM中来执行。WINCE支持我们在单个系统中构建(construct)多个XIP区域&#xff0c;基于下面的理由使用多个XIP区域来代替…

【转】How to install VNC server on ubuntu 14.04

转自&#xff1a;https://www.krizna.com/ubuntu/install-vnc-server-ubuntu-14-04/ VNC server is used to share graphical desktop which can be controlled from other computers . This guide is helpful to install VNC server on Ubuntu Desktop 14.04, Ubuntu server …

Nsis 使用1-- 依条件显示自定义页面 custom page on condition

在制作安装程序的时候&#xff0c;我们会经常遇到根据用户的不同选择而随后显示不同的安装信息采集页面。 其实很简单&#xff0c;在使用NSIS的时候发现了这么个方法&#xff0c;记下来防止自己忘记哈&#xff1a;Code; MUI 2 compatible ------!include "MUI2.nsh"!…

WINCE6.0操作系统---内核(kernel)学习

备注&#xff1a;这里的内核指kernel&#xff0c;其表现形式为kernel.dll&#xff0c;OS指操作系统&#xff0c;core指核心。 图1 WINCE6.0体系结构 1. kernel的组成和功能 WINCE6.0操作系统内(kernel)在代码中的表现形式是kernel.dll(也就是kern.dll)&#xff0c; WINCE5…

【转】WPF调用图片路径,或资源图片

转自&#xff1a;https://www.cnblogs.com/sntetwt/p/5402098.html 一、加载本项目的图片 WPF引入了统一资源标识Uri(Unified Resource Identifier)来标识和访问资源。 其中较为常见的情况是用Uri加载图像。Uri表达式的一般形式为&#xff1a;协议授权路径 协议&#xff1a;pa…

如何自学java迅速成为java高手

很多网友咨询学习Java有没有什么捷径,我说“无他&#xff0c;唯手熟尔”。但是JAVA私塾愿意将一些经验写出来&#xff0c;以便后来者少走弯路,帮助别人是最大的快乐嘛&#xff01; 要想学好Java&#xff0c;首先要知道Java的大致分类。我们知道&#xff0c;自从Sun推出Java以来…

WINCE6.0体系结构学习

WINCE6.0的体系结构图如下图所示&#xff1a; 图1 WINCE的体系结构 根据上图可以把WINCE6.0体系结构分为硬件层、OEM层、操作系统层和应用层&#xff0c;这四层紧密合作&#xff0c;相互配合来完成从应用程序的调用到对硬件的操作和交互。 1. 硬件层 硬件平台的核心是嵌入…

【转】DICOM图像像素值(灰度值)转换为CT值

转自&#xff1a;https://www.cnblogs.com/xuhui24/p/6193032.html https://zhuanlan.zhihu.com/p/358770379 CT值的单位是Hounsfield&#xff0c;简称为Hu&#xff0c;范围是-1024-3071。用于衡量人体组织对X射线的吸收率&#xff0c;设定水的吸收率为0Hu。 在DICO…

无限级分类查询

关于无限级分类的查询问题 分类表cataid parentid1 02 13 14 25 2 表 table1 id cataid title 一个分类信息表&#xff0c;根类别是parentid为0的 这时要查询出类别1下面的所有内容&#xff0c;怎么查&#xff0c;&#xff1f;转载于:https://www…

C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别

一般我们进行成员变量初始化用两种方法 第一种是通过在构造函数内赋值 class Point{public:Point(){ _x 0; _y 0;};Point( int x, int y ){ _x 0; _y 0; }private:int _x, _y;}; 第二种是使用初始化列表 class Point{public:Point():_x(0),_y(0){};Point( int x, int y ):_…