滑雪 (北京大学ACM-ICPC竞赛训练暑期课 )

描述Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长的滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子

 1  2  3  4 516 17 18 19 615 24 25 20 714 23 22 21 813 12 11 10 9

一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。输入输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。输出输出最长区域的长度。样例输入

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

样例输出

25
#include <bits/stdc++.h>
using namespace std;

int dir[4][2]={-1,0,0,1,1,0,0,-1};
int a[101][101],len[101][101];
int n,m;
int dfs(int x,int y)
{
    if(len[x][y]) return len[x][y];
    int mx=0,s;
    for(int i=0;i<4;i++)
    {
        int nx=x+dir[i][0],ny=y+dir[i][1];
        if(nx>=0 && nx<n && ny>=0 && ny<m && a[nx][ny] < a[x][y])
        {
            s=dfs(nx,ny);
            if(s>mx)
                mx=s;
        }
    }

    return len[x][y] = mx+1;
}
int main()
{
    int mx=-1;
    cin>>n>>m;
    memset(len,0,sizeof(len));
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            cin>>a[i][j];
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            if(dfs(i,j) > mx)
                mx=len[i][j];
    cout<<mx<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/Shallow-dream/p/11553126.html

时间: 2024-10-08 15:16:37

滑雪 (北京大学ACM-ICPC竞赛训练暑期课 )的相关文章

Aggressive cows (北京大学ACM-ICPC竞赛训练暑期课 )

描述Farmer John has built a new long barn, with N (2 <= N <= 100,000) stalls. The stalls are located along a straight line at positions x1,...,xN (0 <= xi <= 1,000,000,000). His C (2 <= C <= N) cows don't like this barn layout and become a

简单的整数划分问题 ( 北京大学ACM-ICPC竞赛训练暑期课 )

描述 将正整数n 表示成一系列正整数之和,n=n1+n2+…+nk, 其中n1>=n2>=…>=nk>=1 ,k>=1 .正整数n 的这种表示称为正整数n 的划分.正整数n 的不同的划分个数称为正整数n 的划分数. 输入标准的输入包含若干组测试数据.每组测试数据是一个整数N(0 < N <= 50).输出对于每组测试数据,输出N的划分数.样例输入 5 样例输出 7 提示5, 4+1, 3+2, 3+1+1, 2+2+1, 2+1+1+1, 1+1+1+1+1 #i

棋盘问题 (北京大学ACM-ICPC竞赛训练暑期课 )

描述在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C.输入输入含有多组测试数据.每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目. n <= 8 , k <= n当为-1 -1时表示输入结束.随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保

POJ 4979 海贼王之伟大航路 【状压dp】【北大ACM/ICPC竞赛训练】

该死的题让我想起来艾斯之死... 首先想到dp(i)代表从1到[i表示的这些岛屿]所花的最小时间,然后每次枚举最后一个岛屿以此缩小范围,但发现枚举了最后一个岛屿后没有办法转移,因为不知道倒数第二个岛屿是什么,随着倒数第二个岛屿的不同,时间的增加也会不同,也就是不具备[无后效性]. 因此想到再加一个参数去约束当前问题的状态,dp(i,j)代表1到[i代表的这些点]所需的最少时间,且这趟旅程的最后一个岛屿是j,这样就可转移了,每次枚举倒数第二岛屿:答案就是dp( (1<<n) -1,n ) 具体的

POJ 6048 泰国佛塔 【dfs搜索】【疯狂剪枝!】【北大ACM/ICPC竞赛训练】

1 #include<iostream> 2 #include<cmath> 3 using namespace std; 4 5 int volumn[25],minArea[25];//volumn[i]为第i层到第1层蛋糕所用最小体积 6 int ans,n,m; //minArea[i]为第i层到第1层蛋糕所用[最小侧面积] 7 int area;//当前dfs状态所需要用的表面积 8 9 int maxV(int level,int r,int h){//用level层蛋

HDU 5025 Saving Tang Monk【bfs搜索】【北大ACM/ICPC竞赛训练】

bfs的难点在于怎么去表示一个问题的状态[也就是如何去判重] 1 #include<iostream> 2 #include<queue> 3 #include<cstring> 4 #include<map> 5 using namespace std; 6 7 struct node{ 8 int r,c; 9 int keys; 10 int kill;//记录当前杀死守卫的状态 11 int d;//时间 12 bool operator <

POJ Find the Winning Move【minmax搜索+alpha-beta剪枝】【北大ACM/ICPC竞赛训练】

1 #include<iostream> 2 using namespace std; 3 4 int row,col,chess; 5 char board[5][5]; 6 7 int minSearch(int i,int j,int alpha); 8 int maxSearch(int i,int j,int beta); 9 10 11 bool check(int r,int c){ 12 if( board[r][0]==board[r][1] && board

POJ 8471 切割回文 【dp】【北大ACM/ICPC竞赛训练】

1 #include<iostream> 2 #include<vector> 3 #define INF 100000 4 using namespace std; 5 6 string s; 7 char a[1005]; 8 vector<int> hui[1005];//hui[i]里的k指 k到i组成回文 9 int dp[1005];//dp[i]代表前i个字符要切几刀 10 11 int main(){ 12 int t; cin>>t; 13

POJ 1194 Zipper 【dp】【北大ACM/ICPC竞赛训练】

现在做dp题有点感觉了,以前估计会觉得这题很难,现在觉得这是道不是很水的水题 dp[i][j]代表A里前i个加上B里前j个能不能组成C的前i+j个. 至于怎么想到的呢,n是200,有1000组数据,所以猜测要dp二维,然后很容易就想到了. 这里再考虑到C[i+j]的这个元素肯定是由A[i]或B[j]组成(即A的最末尾或B的最末尾,因为要保证原来的order) 所以这就变成了dp[i][j] = dp[i-1][j] | dp[i][j-1]  (当然这是A[i]=B[j]=C[i+j])的情况.