[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     

 

 

 

 

 

posted @ 2014-03-10 22:39  SXISZERO  阅读(324)  评论(0编辑  收藏  举报