動態規劃 補充

.滑雪問題

      上

左   A    右

  下

依然和“數塔”一樣,從某一點出發,面臨多個選擇(往上,往左,往下,往右)從中選擇一條最優值路徑(滑雪距離最長)

若對A點求,很顯然它的最大值就爲: Max(上,右,下,左) + 1

因此對於任意位置[i,j], 其狀態轉移方程爲:m[i][j] = Max(m[i-1][j] , m[i][j+1] , m[i+1][j] , m[i][j-1]) + 1

由於這道題很難畫出它的路徑圖(起點和終點都不知道)因此很難用“列表格”的方式自底向上求解,因此我們採用備忘錄法:

 
 
 
#include    <stdio.h>
#include    <string.h>
#define        N    101
int a[N][N] , m[N][N] , r , c;
int OK(int i ,int j)
{
    return (i >= 1 && i <= r && j >= 1 && j <= c);
}
int search(int i , int j)
{
    int k;
    if(m[i][j] > 0)    return    m[i][j];
    if(OK(i - 1, j) && a[i][j] > a[i - 1][j])
    {
        k = search(i - 1, j) + 1;
        m[i][j] = m[i][j] < k ? k : m[i][j];
    }
    if(OK(i, j + 1) && a[i][j] > a[i][j + 1])
    {
        k = search(i, j + 1) + 1;
        m[i][j] = m[i][j] < k ? k : m[i][j];
    }
    if(OK(i + 1, j) && a[i][j] > a[i + 1][j])
    {
        k = search(i + 1, j) + 1;
        m[i][j] = m[i][j] < k ? k : m[i][j];
    }
    if(OK(i, j - 1) && a[i][j] > a[i][j - 1])
    {
        k = search(i, j - 1) + 1;
        m[i][j] = m[i][j] < k ? k : m[i][j];
    }
    return    m[i][j] ;
}
int main(void)
{
    int i , j , k , t;
    while(scanf("%d%d", &r, &c) != EOF)
    {
        for(i = 1 ; i <= r ; i++)
            for(j = 1 ; j <= c ; j++)
                scanf("%d", &a[i][j]);
        memset(m, 0, sizeof(m)); k = 0;
        for(i = 1 ; i <= r ; i++)
            for(j = 1 ; j <= c ; j++)
            {
                t = search(i, j);
                k = k < t ? t : k;
            }
        printf("%d\n", k + 1);
    }
    return    0;
}
 
 
Worm問題,這題和免費餡餅幾乎是一樣的,我們同樣可以使用“列表格”的方式自底向上求解:
 
 
代碼
#include    <stdio.h>
#include    <string.h>
#define        N    100
int a[N][N];
int main(void)
{
    int t , x , n , p , m , T;
    while(scanf("%d%d%d%d", &n, &p, &m, &T) != EOF) //蘋果樹n,毛毛蟲其實位置p,m分鐘,終點位置T
    {       
        memset(a, 0, sizeof(a));
        a[m][T] = 1;
        for(t = m - 1; t >= 0 ; t--)
        {
            a[t][1] +=  a[t + 1][2];
            for(x = 2 ; x < n ; x++)
                a[t][x] += a[t + 1][x - 1] + a[t + 1][x + 1];
            a[t][n] += a[t + 1][n - 1];
        }
        printf("%d\n", a[0][p]);
    }
    return    0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章