动态规划 之 dp + 图搜索

/*
// 典型的动态规划,用递归下的记忆化搜索来实现,得用递归,因为你根本不知道从哪里开始,即cnt[0][0]不知道是多少
// 状态转移方程 合法的情况下:DP(i,j) = max( DP(i,j-1), DP(i,j+1), DP(i-1,j), DP(i+1,j) ) + 1;
#include <iostream>
using namespace std;
const int m_size = 105;
int cnt[m_size][m_size],matrix[m_size][m_size];
int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
int row,col;
bool ok(const int &x,const int &y)
{
    return (x>=0&&x<row && y>=0&&y<col);
}
// 如果已经处理过,直接返回(记忆化搜索效率之所以高的原因:不重复计算)
int dp(const int &x,const int &y)
{
    // 将结果记录在cnt数组中(记忆化搜索的重点)
	// 如果左右上下都没有一个点的值比这个点的值大,则cnt[i][j] = max+1 = 1
	// 否则将左右上下各点最大滑雪长度记录在max中, 则cnt[i][j] = max+1
	// 这就是max为什么要初始化为0的原因.
    int dx,dy,i;
    int max = 0;
    if(cnt[x][y]>0)
        return cnt[x][y];
    for(i=0;i<4;i++)
    {
        dx = x + dir[i][0];
        dy = y + dir[i][1];
        if(ok(dx,dy) &&matrix[x][y]>matrix[dx][dy] )
        {
            if(max<dp(dx,dy))
                max = dp(dx,dy);
        }
    }
    return (cnt[x][y] = max + 1);
}
void print_max()
{
    int i,j;
    for(i=0;i<row;i++)
        for(j=0;j<col;j++)
            if(cnt[0][0]<cnt[i][j])
                cnt[0][0] = cnt[i][j];
    cout << cnt[0][0] << endl;
}
int main()
{
    int i,j;
    while(cin>>row)
    {
        cin >> col;
        for(i=0;i<row;i++)
            for(j=0;j<col;j++)
            {
                cin >> matrix[i][j];
                cnt[i][j] = 0;
            }
        for(i=0;i<row;i++)
            for(j=0;j<col;j++)
            {
                dp(i,j);
            }
        print_max();
    }
}
 
 
这是滑雪球问题,dp + 类似图的搜索,动态规划关键在于根据题意定义dp的含义 和 写出状态转移方程。

你可能感兴趣的:(C++,dp,动态规划)