[TYVJ] P1004 滑雪

滑雪

 

背景 Background
成成第一次模拟赛 第三道
 
描述 Description
    trs喜欢滑雪。他来到了一个滑雪场,这个滑雪场是一个矩形,为了简便,我们用r行c列的矩阵来表示每块地形。为了得到更快的速度,滑行的路线必须向下倾斜。
    例如样例中的那个矩形,可以从某个点滑向上下左右四个相邻的点之一。例如24-17-16-1,其实25-24-23…3-2-1更长,事实上这是最长的一条。
 
输入格式 InputFormat
输入文件

第1行: 两个数字r,c(1<=r,c<=100),表示矩阵的行列。
第2..r+1行:每行c个数,表示这个矩阵。
 
输出格式 OutputFormat
输出文件

仅一行: 输出1个整数,表示可以滑行的最大长度。
 
样例输入 SampleInput [复制数据]

5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

 

样例输出 SampleOutput [复制数据]

25

 

题解:

     读完题第一个想法是记忆化搜索,据网上一些大牛介绍此方法可以AC。但思考了一段时间,发现可以转化为动态规划问题,这样会更简单,效率也很高。主要思路如下:

1.把二维矩阵拉成线性。用一个一维数组记录矩阵中所有数据a[i],另两个一维数组b[i],c[i]分别记录数据的X,Y坐标。

2.a[i]从小到大排序,b[i],c[i]跟随排序。

3.现在求最长路径就转化成了求该一维数组a[i]的最长上升子序列。这里要特别注意状态转移的条件。即a[i]、a[j]在矩阵中必须相邻,即abs(xi-xj)=1 && yi=yj或者 xi=xj &&abs(yi-yj)=1。 

4.最后最长上升子序列的长度就是可以滑行的最大长度。

代码:

 

 1 #include<stdio.h>

 2 #include<math.h>

 3 int

 4     r,c1,i,j,n,num=0,maxx=1,a[11000],b[11000],c[11000],f[11000];

 5 int 

 6 max(int a,int b)

 7 {

 8     if (a>b) return(a);

 9     else return(b);

10 }

11 

12 void

13 qsort(int head,int tail)

14 {

15     int i,j,x,y,z;

16     i=head;j=tail;

17     x=a[head];y=b[head];z=c[head];

18     while(i<j)

19     {

20         while((i<j)&&(a[j]>=x)) j--;

21         a[i]=a[j];b[i]=b[j];c[i]=c[j];

22         while((i<j)&&(a[i]<=x)) i++;

23         a[j]=a[i];b[j]=b[i];c[j]=c[i];

24     }

25     a[i]=x;b[i]=y;c[i]=z;

26     if (head<(i-1)) qsort(head,i-1);

27     if ((i+1)<tail) qsort(i+1,tail);

28 }

29 int

30 check(int x1,int y1,int x2, int y2)

31 {

32     int p,q;

33     p=abs(x1-x2);

34     q=abs(y1-y2);

35     if ((p==1)&&(y1==y2)) return 1;

36     if ((x1==x2)&&(q==1))  return 1; 

37         return 0;

38 }

39 

40 int

41 main(void)

42 {

43     int x;

44     scanf("%d%d\n",&r,&c1);

45     for(i=1;i<=r;i++)

46         for (j=1;j<=c1;j++)

47         {

48          scanf("%d",&x);

49          num++;

50          a[num]=x;

51          b[num]=i;

52          c[num]=j;

53         }

54         n=num;

55    

56        

57      qsort(1,n);

58     

59     for (i=1;i<=n;i++)  f[i]=1;    

60     

61     for (i=2;i<=n;i++)

62         for (j=1;j<i;j++)

63         {

64             if ((a[j]<a[i])&&(check(b[j],c[j],b[i],c[i])==1))

65             f[i]=max(f[i],f[j]+1);

66             if (f[i]>maxx) maxx=f[i];

67         }

68     printf("%d\n",maxx);

69     return 0;

70 }

71     

 

 

 

 

 

你可能感兴趣的:(T)