动态规划

基本思想:

    动态规划(Dynamic programming,DP),通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量: 一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。

步骤:

    1. 找出最优解的性质,并刻画其结构特征

    2. 递归定义最优值

    3. 以自底向上的方式计算出最优值

    4. 根据计算最优值得到的信息,构造一个最优解

重要性质:

    1. 最优子结构

    2. 重叠子问题

范例:

     1. 最短路径

#include<iostream>
#include<string.h>
using namespace std;
#define LENGTH 5
/*
 matrix   图
 minPath  临时数组 
 visit    是否访问
 LENGTH   点数
 MinDistance(v)  出发点到v的最短距离
 Fk(u) 表示从Sk中的点u到终点的距离  
 Sk 表示某点的子边集合  
*/
int matrix[LENGTH][LENGTH] = {
    0,10,0,30,100,
    0,0,50,0,0,
    0,0,0,0,10,
    0,0,20,0,60,
    0,0,0,0,0,
};
int minPath[LENGTH];
bool visit[LENGTH];

/* 递归深度搜索 */
int MinDistance(int v)
{
    if(minPath[v] > 0) return minPath[v];
    if(v == LENGTH -1) return 0;
    int min = 1000,t,j;
    for(int i = 0;i < LENGTH;i++) 
    {
        if(matrix[v][i] > 0 && visit[i] == false) 
        {
           visit[i] = true;
           /* 动态方程式 MinDistance(u) = min{w(u,v) + MinDistance(v)} */
           t = MinDistance(i) + matrix[v][i];
           visit[i] = false;
           if(min > t)
           {
               min = t;
               j = i;
           }
        }
    }
    minPath[v] = min;
    return minPath[v];
}

/* 迭代搜索 */
int MinDistanceEx()
{
    minPath[0] = 1000;
    for(int i = 0;i < LENGTH;i++)
    {
        for(int j = 0;j < LENGTH;j++)
        {
            if(matrix[i][j] > 0)
            {
                /* 状态方程式 Fk(u) = min{w(u,v) + Fk+1(v)} */
                if(i > 0)
                {
                    /* 刷新自己到出发点最短距离 */
                    if(minPath[j] > minPath[i] + matrix[i][j])
                    {
                        minPath[j] = minPath[i] + matrix[i][j];
                    }
                    /* 刷新其他结点到出发点最短距离 */
                    for(int k = 0;k < LENGTH;k++)
                    {
                        if(k != j && matrix[j][k] > 0 && minPath[k] > minPath[j] + matrix[j][k])
                        {
                            minPath[k] = minPath[j] + matrix[j][k];
                        }
                    }
                }
                else
                {
                    minPath[j] = matrix[i][j];
                }
            }
        }
    }

    return minPath[LENGTH-1];
}

int main(void)
{
    for(int i = 0;i < LENGTH;i++)
    {
        trace[i] = 0;
        minPath[i] = 1000;
        visit[i] = false;
    }
    //int minD = MinDistance(0);
    int minD = MinDistanceEx();
    std::cout<<"minD:"<<minD<<std::endl;
    return 0;
}


 2 最长公共子序列

#include <stdio.h>
#include <iostream>
#include <string.h>
#define MAXLEN 100

void LCSLength(char *x, char *y, int m, int n, int c[][MAXLEN], int b[][MAXLEN])
{
	int i, j;

	for(i = 0; i <= m; i++)
		c[i][0] = 0;
	for(j = 1; j <= n; j++)
		c[0][j] = 0;
	for(i = 1; i<= m; i++)
	{
		for(j = 1; j <= n; j++)
		{
			if(x[i-1] == y[j-1])
			{
				c[i][j] = c[i-1][j-1] + 1;
				b[i][j] = 0;
			}
			else if(c[i-1][j] >= c[i][j-1])
			{
				c[i][j] = c[i-1][j];
				b[i][j] = 1;
			}
			else
			{
				c[i][j] = c[i][j-1];
				b[i][j] = -1;
			}
		}
	}
}

void PrintLCS(int b[][MAXLEN], char *x, int i, int j)
{
	if(i == 0 || j == 0)
		return;
	if(b[i][j] == 0)
	{
		PrintLCS(b, x, i-1, j-1);
		printf("%c ", x[i-1]);
	}
	else if(b[i][j] == 1)
		PrintLCS(b, x, i-1, j);
	else
		PrintLCS(b, x, i, j-1);
}

int main(int argc, char **argv)
{
	char x[MAXLEN] = "ABCBDAB";
	char y[MAXLEN] = "BDCABAB";
	int b[MAXLEN][MAXLEN];
	int c[MAXLEN][MAXLEN];
	int m, n;

	m = strlen(x);
	n = strlen(y);

	LCSLength(x, y, m, n, c, b);
	PrintLCS(b, x, m, n);

	return 0;
}

 

 

posted on 2013-01-11 14:30  kangbry  阅读(192)  评论(0编辑  收藏  举报

导航