.滑雪问题
上
左 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
#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);
}
{
return (i >= 1 && i <= r && j >= 1 && j <= c);
}
int search(int i , int j)
{
int k;
{
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];
}
{
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;
{
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]);
{
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;
}
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;
}
return 0;
}
Worm问题,这题和免费馅饼几乎是一样的,我们同样可以使用“列表格”的方式自底向上求解:
代码
#include <stdio.h>
#include <string.h>
#define N 100
#include <string.h>
#define N 100
int a[N][N];
int main(void)
{
int t , x , n , p , m , T;
{
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;
}
{
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;
}