P1004 滑雪
2010-06-21 15:25
211 查看
题目:
描述 Description
trs喜欢滑雪。他来到了一个滑雪场,这个滑雪场是一个矩形,为了简便,我们用r行c列的矩阵来表示每块地形。为了得到更快的速度,滑行的路线必须向下倾斜。
例如样例中的那个矩形,可以从某个点滑向上下左右四个相邻的点之一。例如24-17-16-1,其实25-24-23…3-2-1更长,事实上这是最长的一条。
输入格式 Input Format
输入文件
第1行: 两个数字r,c(1<=r,c<=100),表示矩阵的行列。
第2..r+1行:每行c个数,表示这个矩阵。
输出格式 Output Format
输出文件
仅一行: 输出1个整数,表示可以滑行的最大长度。
样例输入 Sample Input
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
样例输出 Sample Output
25
时间限制 Time Limitation
各个测试点1s
输入处理+排序+最长上升子序列=AC
测试结果:
VijosNT Mini 2.0.5.4
#01: Accepted (0ms, 372KB)
#02: Accepted (0ms, 372KB)
#03: Accepted (0ms, 372KB)
#04: Accepted (0ms, 372KB)
#05: Accepted (0ms, 372KB)
#06: Accepted (0ms, 372KB)
#07: Accepted (0ms, 372KB)
#08: Accepted (0ms, 372KB)
#09: Accepted (231ms, 372KB)
#10: Accepted (246ms, 768KB)
Accepted / 100 / 478ms / 768KB
显然最后两个点的时间的花费较多
因为这里使用的是O(n^2)的时间复杂度的最长单调子序列的算法
至于O(nlogn)的,应该会快很多,该算法将在后面提到
描述 Description
trs喜欢滑雪。他来到了一个滑雪场,这个滑雪场是一个矩形,为了简便,我们用r行c列的矩阵来表示每块地形。为了得到更快的速度,滑行的路线必须向下倾斜。
例如样例中的那个矩形,可以从某个点滑向上下左右四个相邻的点之一。例如24-17-16-1,其实25-24-23…3-2-1更长,事实上这是最长的一条。
输入格式 Input Format
输入文件
第1行: 两个数字r,c(1<=r,c<=100),表示矩阵的行列。
第2..r+1行:每行c个数,表示这个矩阵。
输出格式 Output Format
输出文件
仅一行: 输出1个整数,表示可以滑行的最大长度。
样例输入 Sample Input
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
样例输出 Sample Output
25
时间限制 Time Limitation
各个测试点1s
输入处理+排序+最长上升子序列=AC
#include<iostream> #include<math.h> using namespace std; int quick_sort(int a[][3],int low,int high){ int i=low,j=high,temp=a[low][2],p=a[low][0],q=a[low][1]; if (i>=j)return 0; while(i<j){ while(j>i&&a[j][2]>temp)j--; if (j>i){ a[i][1]=a[j][1]; a[i][0]=a[j][0]; a[i++][2]=a[j][2]; } while(j>i&&a[i][2]<temp)i++; if (j>i){ a[j][1]=a[i][1]; a[j][0]=a[i][0]; a[j--][2]=a[i][2]; } } a[i][2]=temp; a[i][0]=p; a[i][1]=q; quick_sort(a,low,i-1); quick_sort(a,i+1,high); return 0; } int main(){ int r,c; int map[10001][3];//0x1y2num int result[10001]; int i,j; int max1=0; cin>>r>>c; for (i=1;i<=r;i++) { for (j=1;j<=c;j++) { cin>>map[(i-1)*c+j][2]; map[(i-1)*c+j][0]=i; map[(i-1)*c+j][1]=j; } } quick_sort(map,1,r*c); for (i=1;i<=r*c;i++) { result[i]=1; for (j=1;j<i;j++) { if (map[j][2]<map[i][2]&&fabs(map[j][1]-map[i][1])+fabs(map[j][0]-map[i][0])==1){ result[i]=max(result[i],result[j]+1); } } } for (i=1;i<=r*c;i++){ if (result[i]>=max1)max1=result[i]; } cout<<max1; system("pause"); return 0; }
测试结果:
VijosNT Mini 2.0.5.4
#01: Accepted (0ms, 372KB)
#02: Accepted (0ms, 372KB)
#03: Accepted (0ms, 372KB)
#04: Accepted (0ms, 372KB)
#05: Accepted (0ms, 372KB)
#06: Accepted (0ms, 372KB)
#07: Accepted (0ms, 372KB)
#08: Accepted (0ms, 372KB)
#09: Accepted (231ms, 372KB)
#10: Accepted (246ms, 768KB)
Accepted / 100 / 478ms / 768KB
显然最后两个点的时间的花费较多
因为这里使用的是O(n^2)的时间复杂度的最长单调子序列的算法
至于O(nlogn)的,应该会快很多,该算法将在后面提到