参贪心算法
⑴ 贪心算法 活动安排问题
这道题的贪心算法比较容易理解,我就不多说明了,只是提到一下算法思路1、建立数学模型描述问题。我在这里将时间理解成一条直线,上面有若干个点,可能是某些活动的起始时间点,或终止时间点。在具体一下,如果编程来实现的话,将时间抽象成链表数组,数组下标代表其实时间,该下标对应的链表代表在这个时间起始的活动都有哪些,具体参照程序注释。2、问题分解。为了安排更多的活动,那么每次选取占用时间最少的活动就好。那么从一开始就选取结束时间最早的,然后寻找在这个时间点上起始的活动,以此类推就可以找出贪心解。程序代码:#include<stdio.h>
struct inode //自定义的结构体
{
int end; //表示结束时间
inode *next; //指向下一个节点的指针
};int main()
{
inode start[10001],*pt;
int a,b,i,num=0; //num负责计数,i控制循环,a,b输入时候使用
for(i=0;i<10001;i++) //初始化
{
start[i].next=NULL;
}
while(scanf("%d %d",&a,&b)) //输入并建立数据结构
{
if(a==0&&b==0) break;
pt=new inode; //创建新的节点,然后将该节点插入相应的位置
pt->end=b;
pt->next=start[a].next;
start[a].next=pt;
}
i=0;
while(i<10001) //进行贪心算法,i表示当前时间
{
if(start[i].next==NULL)
{
i++; //该时间无活动开始
}
else
{
int temp=10001; //临时变量,存储该链表中最早的终止时间
for(pt=start[i].next;pt!=NULL;pt=pt->next)
{
if(pt->end<temp)
{
temp=pt->end;
}
}
i=temp; //将当前时间设置成前一子问题的终止时间
num++;
}
}
printf("%d\n",num); //打印结果
return 0;
}代码并不一定是最快速的,但是可以求出贪心解,如果你做的是ACM编程题目,不保证能AC注释我尽力写了,希望对你有帮助。
⑵ 程序员都应该精通的六种算法,你会了吗
对于一名优秀的程序员来说,面对一个项目的需求的时候,一定会在脑海里浮现出最适合解决这个问题的方法是什么,选对了算法,就会起到事半功倍的效果,反之,则可能会使程序运行效率低下,还容易出bug。因此,熟悉掌握常用的算法,是对于一个优秀程序员最基本的要求。
那么,常用的算法都有哪些呢?一般来讲,在我们日常工作中涉及到的算法,通常分为以下几个类型:分治、贪心、迭代、枚举、回溯、动态规划。下面我们来一一介绍这几种算法。
一、分治算法
分治算法,顾名思义,是将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
分治算法一般分为三个部分:分解问题、解决问题、合并解。
分治算法适用于那些问题的规模缩小到一定程度就可以解决、并且各子问题之间相互独立,求出来的解可以合并为该问题的解的情况。
典型例子比如求解一个无序数组中的最大值,即可以采用分治算法,示例如下:
def pidAndConquer(arr,leftIndex,rightIndex):
if(rightIndex==leftIndex+1 || rightIndex==leftIndex){
return Math.max(arr[leftIndex],arr[rightIndex]);
}
int mid=(leftIndex+rightIndex)/2;
int leftMax=pidAndConquer(arr,leftIndex,mid);
int rightMax=pidAndConquer(arr,mid,rightIndex);
return Math.max(leftMax,rightMax);
二、贪心算法
贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。
贪心算法的基本思路是把问题分成若干个子问题,然后对每个子问题求解,得到子问题的局部最优解,最后再把子问题的最优解合并成原问题的一个解。这里要注意一点就是贪心算法得到的不一定是全局最优解。这一缺陷导致了贪心算法的适用范围较少,更大的用途在于平衡算法效率和最终结果应用,类似于:反正就走这么多步,肯定给你一个值,至于是不是最优的,那我就管不了了。就好像去菜市场买几样菜,可以经过反复比价之后再买,或者是看到有卖的不管三七二十一先买了,总之最终结果是菜能买回来,但搞不好多花了几块钱。
典型例子比如部分背包问题:有n个物体,第i个物体的重量为Wi,价值为Vi,在总重量不超过C的情况下让总价值尽量高。每一个物体可以只取走一部分,价值和重量按比例计算。
贪心策略就是,每次都先拿性价比高的,判断不超过C。
三、迭代算法
迭代法也称辗转法,是一种不断用变量的旧值递推新值的过程。迭代算法是用计算机解决问题的一种基本方法,它利用计算机运算速度快、适合做重复性操作的特点,让计算机对一组指令(或一定步骤)进行重复执行,在每次执行这组指令(或这些步骤)时,都从变量的原值推出它的一个新值。最终得到问题的结果。
迭代算法适用于那些每步输入参数变量一定,前值可以作为下一步输入参数的问题。
典型例子比如说,用迭代算法计算斐波那契数列。
四、枚举算法
枚举算法是我们在日常中使用到的最多的一个算法,它的核心思想就是:枚举所有的可能。枚举法的本质就是从所有候选答案中去搜索正确地解。
枚举算法适用于候选答案数量一定的情况。
典型例子包括鸡钱问题,有公鸡5,母鸡3,三小鸡1,求m钱n鸡的所有可能解。可以采用一个三重循环将所有情况枚举出来。代码如下:
五、回溯算法
回溯算法是一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。
许多复杂的,规模较大的问题都可以使用回溯法,有“通用解题方法”的美称。
典型例子是8皇后算法。在8 8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问一共有多少种摆法。
回溯法是求解皇后问题最经典的方法。算法的思想在于如果一个皇后选定了位置,那么下一个皇后的位置便被限制住了,下一个皇后需要一直找直到找到安全位置,如果没有找到,那么便要回溯到上一个皇后,那么上一个皇后的位置就要改变,这样一直递归直到所有的情况都被举出。
六、动态规划算法
动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划。
动态规划算法适用于当某阶段状态给定以后,在这阶段以后的过程的发展不受这段以前各段状态的影响,即无后效性的问题。
典型例子比如说背包问题,给定背包容量及物品重量和价值,要求背包装的物品价值最大。
⑶ 甯哥敤镄勭畻娉旷瓥鐣ュ寘𨰾
甯哥敤镄勭畻娉旷瓥鐣ュ寘𨰾浠ヤ笅鍑犱釜鏂归溃锛
1銆佽椽蹇幂畻娉曪细璐蹇幂畻娉曟槸涓绉嶅湪姣忎竴姝ラ夋嫨涓閮介噰鍙栧湪褰揿墠鐘舵佷笅链濂芥垨链浼桡纸鍗虫渶链夊埄锛夌殑阃夋嫨锛屼粠钥屽笇链涘艰嚧缁撴灉鏄链濂芥垨链浼樼殑绠楁硶銆傝椽蹇幂畻娉旷殑镐濊矾鏄浠庨梾棰樼殑灞閮ㄦ渶浼樿В鍑哄彂锛屽敖鍙鑳藉湴瀹炵幇鍏ㄥ眬链浼樿В銆傝椽蹇幂畻娉曞苟涓崭竴瀹氲兘寰楀埌链浼樿В锛屼絾瀹冨彲浠ュ湪澶氶”寮忔椂闂村唴瑙e喅璁稿氶梾棰桡纴濡傛渶灏忕敓鎴愭爲銆佹渶鐭璺寰勭瓑銆
2銆佺墿娴侀嗗烟锛氩湪鐗╂祦棰嗗烟涓锛岀畻娉旷瓥鐣ュ彲浠ョ敤浜庝紭鍖栬繍杈撹矾绾裤侀檷浣庤繍杈撴垚链鍜屾彁楂樿繍杈撴晥鐜囥备緥濡傦纴阃氲繃锷ㄦ佽勫垝绠楁硶锛屽彲浠ユ牴鎹璐х墿镄勭洰镄勫湴鍜岃繍杈挞渶姹傦纴钖堢悊瀹夋帓璐х墿镄勮呰浇鍜岃繍杈撹矾绾匡纴鎻愰珮杩愯緭鏁堢巼骞堕檷浣庢垚链銆
3銆佷汉宸ユ櫤鑳介嗗烟锛氱畻娉旷瓥鐣ユ槸浜哄伐鏅鸿兘棰嗗烟涓镄勯吨瑕佺粍鎴愰儴鍒嗭纴鍙浠ョ敤浜庢満鍣ㄥ︿範銆佽嚜铹惰瑷澶勭悊銆佽$畻链鸿呜夌瓑棰嗗烟銆备緥濡傦纴鍦ㄦ満鍣ㄥ︿範涓锛岄氲繃璐蹇幂畻娉曞拰锷ㄦ佽勫垝绠楁硶绛夌瓥鐣ワ纴鍙浠ヨ缁冩ā鍨嫔苟浼桦寲妯″瀷鍙傛暟锛屾彁楂樻ā鍨嬬殑鍑嗙‘镐у拰娉涘寲鑳藉姏銆
⑷ 贪婪算法指的是什么
贪心算法是指在对问题进行求解时,在每-步选择中都采取最好或者最优(即最有利)的选择,从而希望能够导致结果是最好或者最优的。
贪婪算法所得到的结果不一定是最优的结果(有时候会是最优解),但是都是相对近似(接近)最优解的结果。
例题、区间问题
问题描述:有n项工作,每项工作分别在si开始,ti结束。对每项工作,你都可以选择参加或不参加,但选择了参加某项工作就必须至始至终参加全程参与。
即参与工作的时间段不能有重叠(即使开始的时间和结束的时间重叠都不行)。限制条件:1<=n<=1000001<=si<=ti,=109样例:输入51 2 4 6 83 5 7 9 10输出3(选择工作1, 3, 5)。