chapter10 分治法 动态规划 贪心算法

分治法:算法依次或多次地递归调用自身来解决相关的子问题

                  上楼梯问题:一次只能走1步或2步,上n阶楼梯,有几种上法

                    斐波那契数列

动态规划:把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解,

                 典型例题:LCS,编辑距离,01背包问题

               LCS:  i==0||j==0   c[i][j]=0;

                           i>0 j>0 x[i]=y[j]     c[i][j] = c[i-1][j-1] +1

                           i>0 j> 0 x[i] != y[j]   c[i][j] = max{ c[i, j-1]  ,c[i-1][j] }

               

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

int LCS(char *, char *);
int main(int argc, const char *argv[])
{
    char *s1 = "djasdhak";
    char *s2 = "dyjak";
    int ret = LCS(s1, s2);
    printf("%d\n", ret);
    return 0;
}

int LCS(char *s1, char *s2)
{
    int len1 = strlen(s1);
    int len2 = strlen(s2);
    int cnt[ len1 + 1][ len2 + 1];
    int i,j;
    for(i = 0; i < len1 + 1 ; i++)
        for(j = 0; j < len2 + 1; j++)
            if(i==0 || j==0)
                cnt[i][j] = 0;

    for(i = 1; i <= len1; ++i)
        for(j = 1; j <= len2; ++j)
        {
            if(s1[i-1] == s2[j-1])
                cnt[i][j] = cnt[i-1][j-1] + 1;
            else
            {
                cnt[i][j] = cnt[i-1][j] > cnt[i][j-1] ? cnt[i-1][j] : cnt[i][j-1];
            }
        }
    return cnt[len1][len2];
}

               编辑距离:http://www.cnblogs.com/wj9012/p/3919592.html 

                               i==0  c[i][j] = j

                               j==0  c[i][j] = i

                              s1[i-1] == s2[j-1]   c[i][j] = c[i-1][j-1]

                              s1[i-1] != s2[j-1]   c[i][j] = min{ c[i-1][j-1], c[i][j-1], c[i-1][j] }

            01背包问题:

                               j < c[i]  f[i][j]=f[i-1][j]  -->物体i重量比背包容量大

                              max{ f[i-1][j], f[i-1][j-c[i] ] +w[i] }  -->选取放入i和不放入i的最大值  

              

//01背包问题,3件物品,背包容纳5kg,物体1重1kg价值60元,物体2重2kg价值100元,物体3重3kg价值120元,怎么最大化背包所装价值
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int backbag(int [][6], int *, int *, int);

int main(int argc, const char *argv[])
{
    int N = 3;
    int V = 5;
    int C[4] = {0, 1, 2, 3};
    int W[4] = {0, 60, 100, 120};
    int f[N+1][V+1];
    int ret = backbag(f, C, W, N+1);
    printf("%d\n", f[N][V]);
    return 0;
}

int backbag(int p[][6], int *c, int *w, int N)
{
    int i, j;
    for(i = 0; i < 6; ++i)
        p[0][i] = 0;
    for(i = 1; i < N; ++i)
    {
        p[i][0] = 0;
        for(j = 1; j < 6; ++j )
        {
            if(j < c[i])
            {
                p[i][j] = p[i-1][j];
            }
            else
            {
                p[i][j] = (p[i-1][j] > (p[i-1][j-c[i]] + w[i]) ?  p[i-1][j] : (p[i-1][j-c[i]] + w[i]) );
            }
        }
    }
}

                  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值