获得徽章 0
- #挑战每日一条沸点#
贪心算法
贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。
2.贪心选择是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素。
3.当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。运用贪心策略在每一次转化时都取得了最优解。问题的最优子结构性质是该问题可用贪心算法求解的关键特征。贪心算法的每一次操作都对结果产生直接影响。贪心算法对每个子问题的解决方案都做出选择,不能回退。
4.贪心算法的基本思路是从问题的某一个初始解出发一步一步地进行,根据某个优化测度,每一步都要确保能获得局部最优解。每一步只考虑一个数据,他的选取应该满足局部优化的条件。若下一个数据和部分最优解连在一起不再是可行解时,就不把该数据添加到部分解中,直到把所有数据枚举完,或者不能再添加算法停止。展开评论点赞 - #挑战每日一条沸点#
求从(0,0)到每一个点的最小路径和
思想,和上面类似,只不过f(m,n)的含义是(0,0)到(m,n)的最小路径和,因为是从左上角开始每次只能向右走或者向下走,只要我们知道一个点的左边的点和上边的点的最小路径和,比较这两个点的大小,用小的路径和加上当前点的值就是(0,0)到当前点的最小路径和即:
f(m,n) = Min( f(m - 1, n) , f(m,n - 1) ) + 坐标(m,n)显示的值
易得最小问题也是,在矩阵的上边界和左边界,因为(0,0)到上边界和左边界的点路径只有一条,所以最小路径和是确定的。我们求出上边界和左边界的所有点的最小路径和之后,就能通过公式继续一步一步的求下面的点的最小路径和。展开评论点赞 - #挑战每日一条沸点#
从(0,0)到每一个点有几种走法。
我们继续用动态规划的思想分析:
到(m,n)这个点,只能通过(m - 1, n)或者 (m,n - 1)这两个点即:
f(m,n) = f(m - 1,n) + f(m,n - 1) ,f(m,n)函数的意思就是(0,0)到(m,n)有几条路径
那分到什么程度,才是易得答案呢,分到(m,n)坐标的其中一个是0的时候,因为是从左上角开始每次只能向右走或者向下走,当有一个是0的时候说明这个坐标在矩形的左边界或者上边界,这是从(0,0)到这个点只有一条路径。展开评论点赞 - #挑战每日一条沸点#
动态规划法与分治法区别
动态规划算法与分治法最大的差别是:适合于用动态规划法求解的问题,经分解后得到的子问题往往不是互相独立的(即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解)评论点赞 - #挑战每日一条沸点#
动态规划法
定义:
动态规划算法是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决。
动态规划算法的基本思想与分治法类似,也是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,最后一个子问题就是初始问题的解。展开评论点赞 - #挑战每日一条沸点#
合并排序
排序位于[begin, end)中的整数
void sort(int *begin,int *end)
{
int size=end-begin;
int*p,*p1,*p2,*mid=begin+size/2;
if(size<=1)return;//边界条件
sort(begin,mid);//递归求解
sort(mid,end);
p=(int*)malloc(size*sizeof(int));//申请临时空间
for(p1=begin,p2=mid;p1!=mid||p2!=end;)//合并有序表
*p++=(p2==end||p1!=mid&&*p1<*p2)?(*p1++):(*p2++);
for(p-=size;begin!=end;)//回填
*begin++=*p++;
free(p-size);//释放临时空间
}
展开评论点赞 - #挑战每日一条沸点#
合并排序C语言
#include <malloc.h>
#include <stdlib.h>
void mergesort(int*a,int length){
int step;
int*p,*q,*t;
int i,j,k,len1,len2;
int *temp;
step=1;
p=a;
q=(int*)malloc(sizeof(int)*length);
temp=q;
while(step<length){
i=0;
j=i+step;
k=i;
len1=i+step<length?i+step:length;
len2=j+step<length?j+step:length;
while(i<length){
while(i<len1&&j<len2){
q[k++]=p[i]<p[j]?p[i++]:p[j++];
}
while(i<len1){
q[k++]=p[i++];
}
while(j<len2){
q[k++]=p[j++];
}
i=j;
j=i+step;
k=i;
len1=i+step<length?i+step:length;
len2=j+step<length?j+step:length;
}
step*=2;
t=p;
p=q;
q=t;
}
if(a!=p){
memcpy(a,p,sizeof(int)*length);
}
free(temp);
}
void main(void){
int arrary[]={9,6,1,3,8,4,2,0,5,7};
mergesort(arrary,10);
}展开评论点赞 - #挑战每日一条沸点#
合并排序
JAVA
public static void mergeSort(int[]array){
int length=array.length;
int middle=length/2;
if(length>1){
int[]left=Arrays.copyOfRange(array,0,middle);//拷贝数组array的左半部分
int[]right=Arrays.copyOfRange(array,middle,length);//拷贝数组array的右半部分
mergeSort(left);//递归array的左半部分
mergeSort(right);//递归array的右半部分
merge(array,left,right);//数组左半部分、右半部分合并到Array
}
}
//合并数组,升序
private static void merge(int[]result,int[]left,int[]right){
int i=0,l=0,r=0;
while(l<left.length&&r<right.length){
if(left[l]<right[r]){
result[i]=left[l];
i++;
l++;
}else{
result[i]=right[r];
i++;
r++;
}
}
while(r<right.length){//如果右边剩下合并右边的
result[i]=right[r];
r++;
i++;
}
while(l<left.length){
result[i]=left[l];
l++;
i++;
}
}展开评论点赞 - #挑战每日一条沸点#
合并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
合并排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。合并排序也叫归并排序。展开评论点赞 - #挑战每日一条沸点#
实践题目:
给定一个顺序表,编写一个求出其最大值和最小值的分治算法。
分析:
由于顺序表的结构没有给出,作为演示分治法这里从简顺序表取一整形数组数组大小由用户定义,数据随机生成。我们知道如果数组大小为 1 则可以直接给出结果,如果大小为 2则一次比较即可得出结果,于是我们找到求解该问题的子问题即: 数组大小 <= 2。到此我们就可以进行分治运算了,只要求解的问题数组长度比 2 大就继续分治,否则求解子问题的解并更新全局解
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define M 40
/* 分治法获取最优解 */
void PartionGet(int s,int e,int *meter,int *max,int *min){
/* 参数:
* s 当前分治段的开始下标
* e 当前分治段的结束下标
* meter 表的地址
* max 存储当前搜索到的最大值
* min 存储当前搜索到的最小值
*/
int i;
if(e-s <= 1){ /* 获取局部解,并更新全局解 */
if(meter[s] > meter[e]){
if(meter[s] > *max)
*max = meter[s];
if(meter[e] < *min)
*min = meter[e];
}
else{
if(meter[e] > *max)
*max = meter[e];
if(meter[s] < *min)
*min = meter[s];
}
return ;
}
展开评论点赞