您的位置:首页 > 理论基础 > 数据结构算法

【诺坎普的酋长的学习历程】算法与数据结构【一】

2017-01-08 11:32 381 查看
        之前学习java,安卓一直想把自己的学习历程写成博客,但是之前确实是太懒惰,一直没写,现在开始学习算法和数据结构就不定期写写学到的东西,写的也很乱,就当作学习笔记,给自己看,或者如果能帮助到大家也是很好的,如果大家发现里面有什么错误,希望指出(毕竟本人是新手,刚刚迈入编程的大门三个月)

        注意!!!本文非教程,仅仅是自己的学习笔记,可参考(但我怀疑里面会有些错误,希望大家指出)。

        开更!

                                                                                                         第一节 算法之简单的动态规划

        动态规划是一种在多学科中普遍被使用的算法,它把一个复杂的问题分为若干重叠子问题,从而达到简化运算的效果,可以大大减少运行时间。动态规划的四个特点分别是1:具有最优子结构,这条是说当子问题最优的时候,父问题一定可以选择出一个最优解,具有这样的结构叫做最优子结构。2:子问题重叠,即父问题和子问题的实质是一样的,或者说问法和求解办法以及结果都是一类的问题叫做子问题重叠。3:具有边界,如果没有边界,子问题将会“无穷匮也”,那么我们就无法完成要求。4:子问题要相互独立,这就是说没有继承关系的子问题之间互不干扰,彼此独立,任何一个子问题的最优解都不影响父问题选择其他子问题的最优解。

        这里用经典的01背包问题来举例。

        假设你有一个容积为sm的背包,有n件物品,每件物品具有自己的价值和重量,现在想请你找出怎样装包可以让一个包内的物品品价值最大。

        为什么这个题目可以用动态规划的方法去解,首先,它具有最优子结构,当你选定最后一个物品的放进与否为一个父问题时,子问题总能找出一个最优情况,然后你只需要比较最后是装总价值大还是不装总价值大,其次,父问题和子问题是重叠的,每一个自问题都可以看作是下一件物品装与否的父问题,第三,当决定第一件物品装载与否的时候,即到达边界,最后,每一件物品的装与不装所造成的最后结果都是彼此独立互不影响的。因此这道题可以使用动态规划的方法来解决。

        现在来分析它的最优子结构,当物品只有一件时,只需比较这件物品的重量和包的容积,如果物品的重量大于包的容积,总价值就是物品的价值,否则总价值就是0.这也就是子问题的边界。用逻辑表达式写出来是这样子的

        if(n==1)

        {

               if(weight[0]<=sm)

                      vm = value[0];

               else

                      vm = 0;

         }

这里weight这个数组就代表每一件物品的质量,value数组代表每一件物品的价值,vm是总价值,sm是包的容积

        当n大于等于2时,对于每一个子问题(或者是父问题)都只有两种选择可以做,第一,就是选择省出空间装之前几件物品,第二,就是装本件物品,获得对应的价值,但是用去了一点包的空间。然后只需要比较这两种方案哪一种更优就选择哪一种,用逻辑表达式写出来是这样

        vm(sm,n) = max[vm(sm,n-1),value[n-1] + vm(sm-weight[n-1],n-1)]

在这个式子中,vm是总价值函数。

        这样一来,背包问题就得到了解决。

        下面贴上完整代码。

#include<stdio.h>
int beibao(int sm,int n,int weight[100],int value[100]);
int main(){
int sm,n,vm;
printf("请输入背包的容积和物品的件数\n");
scanf("%d%d",&sm,&n);
int i;
int weight
;
int value
;
printf("请输入每一件物品的重量与价值\n");
for(i=0;i<n;i++)
{
scanf("%d%d",&weight[i],&value[i]);
}
vm = beibao(sm,n,weight,value);
printf("%d",vm);
return 0;
}
int beibao(int sm,int n,int weight[100],int value[100])
{

if(n==1)
{
if(weight[0]<=sm)
return value[0];
else
return 0;
}
else
{
if((value[n-1]+beibao(sm-weight[n-1],n-1,weight,value))>=(beibao(sm,n-1,weight,value)))
return value[n-1]+beibao(sm-weight[n-1],n-1,weight,v
9478
alue);
else
return beibao(sm,n-1,weight,value);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: