#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m;
int maps[105][105];
int dp[105][105];
int ds[4]= {1,0,-1,0};
int dy[4]= {0,1,0,-1};
struct node
{
int s,y;
int op;
} point[10005];
int judge(int a,int b)
{
if(a>=1&&a<=n&&b>=1&&b<=m)
return 1;
return 0;
}
int com(node a,node b)
{
return a.op<b.op;
}
int main()
{
scanf("%d%d",&n,&m);
int temp=0;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
point[temp].s=i;
point[temp].y=j;
scanf("%d",&point[temp++].op);
maps[i][j]=point[temp-1].op;
}
}
sort(point,point+temp,com);
int an=0;
for(int i=0; i<temp; i++)
{
for(int j=0; j<4; j++)
{
int a=point[i].s+ds[j];
int b=point[i].y+dy[j];
if(judge(a,b))
{
if(maps[point[i].s][point[i].y]>maps[a][b])
{
dp[point[i].s][point[i].y]=max(dp[a][b]+1, dp[point[i].s][point[i].y]);
an=max(an,dp[point[i].s][point[i].y]);
}
}
}
}
/*for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
printf("%d ",dp[i][j]);
}
printf("\n");
}*/
printf("%d\n",an+1);
}
先将按高度从低到高排一遍。
dp[i][j]=ma(dp[i][j],dp[a][b]+1);
第一感觉像搜索。 但好像以前写过超时。
找到了。但不知道对错。也没剪枝。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int maps[105][105];
int book[105][105];
int r,cc;
int an;
int maa;
int fc[4]={1,0,-1,0};
int fy[4]={0,1,0,-1};
int check(int i,int j)
{
if(i>=1&&i<=r&&j>=1&&j<=cc)
return 1;
else return 0;
}
int check2(int i,int j)
{
for(int k=0;k<4;k++)
{
int a=i+fc[k];
int b=j+fy[k];
if(maps[i][j]>maps[a][b]&&check(a,b))
return 0;
}
return 1;
}
int dfs(int i,int j)
{
if(check2(i,j))
return maa=max(maa,an);
if(book[i][j]==1)
return 0;
book[i][j]=1;
int temp=0;
for(int k=0;k<4;k++)
{
int c,y;
c=i+fc[k];
y=j+fy[k];
if(maps[i][j]>maps[c][y]&&check(c,y))
{
an++;
dfs(c,y);
book[c][y]=0;
an--;
}
}
}
int main()
{
scanf("%d%d",&r,&cc);
for(int i=1;i<=r;i++)
{
for(int j=1;j<=cc;j++)
{
scanf("%d",&maps[i][j]);
}
}
maa=0;
for(int i=1;i<=r;i++)
{
for(int j=1;j<=cc;j++)
{
memset(book,0,sizeof(book));
an=0;
dfs(i,j);
}
}
printf("%d\n",maa+1);
}
记忆化搜索:
#include<iostream>
#include<cstdio>
using namespace std;
int map[105][105];
int f[][2]={{1,0},{0,1},{-1,0},{0,-1}};
int vis[105][105] ;
int m , n ;
int DFS ( int x , int y )
{
if ( vis[x][y] != -1 )
return vis[x][y] ;
int i ;
int sum = 1 ;
for ( i = 0 ; i < 4 ; i ++ )
{
int s = x + f[i][0] ;
int t = y + f[i][1] ;
if ( s < 0 || t < 0 || s >= m || t >= n )
continue;
if ( map[s][t] >= map[x][y] )
continue;
sum = max ( sum , DFS ( s , t ) + 1 ) ;
}
vis[x][y] = sum ;
return sum ;
}
int main()
{
while ( cin >> m >> n )
{
int sum = 0;
int i , j ;
for ( i = 0 ; i < m ; i ++ )
for ( j = 0 ; j < n ; j ++ )
cin >> map [i][j] ;
memset ( vis , -1 , sizeof ( vis ) ) ;
for ( i = 0 ; i < m ; i ++ )
for ( j = 0 ; j < n ; j ++ )
sum = max ( sum , DFS ( i , j ) ) ;
cout << sum << endl ;
}
return 0 ;
}
这个是从网上抄的。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int maps[105][105];
int book[105][105];
int dp[105][105];
int r,cc;
int an;
int maa;
int fc[4]={1,0,-1,0};
int fy[4]={0,1,0,-1};
int check(int i,int j)
{
if(i>=1&&i<=r&&j>=1&&j<=cc)
return 1;
else return 0;
}
int check2(int i,int j)
{
for(int k=0;k<4;k++)
{
int a=i+fc[k];
int b=j+fy[k];
if(maps[i][j]>maps[a][b]&&check(a,b))
return 0;
}
return 1;
}
int dfs(int i,int j)
{
if(dp[i][j])return dp[i][j];
if(book[i][j]==1)
return 0;
book[i][j]=1;
int an=1;
for(int k=0;k<4;k++)
{
int c,y;
c=i+fc[k];
y=j+fy[k];
if(maps[i][j]>maps[c][y]&&check(c,y))
{
int t=1+dfs(c,y);
if(t>an)an=t;
}
}
return dp[i][j]=an;
}
int main()
{
scanf("%d%d",&r,&cc);
for(int i=1;i<=r;i++)
{
for(int j=1;j<=cc;j++)
{
scanf("%d",&maps[i][j]);
}
}
maa=0;
for(int i=1;i<=r;i++)
{
for(int j=1;j<=cc;j++)
{
memset(book,0,sizeof(book));
an=0;
//printf("%d\n",dfs(i,j));
maa=max(maa,dfs(i,j));
}
}
printf("%d\n",maa);
}
Time Limit: 1000MS | Memory Limit: 65536KB | 64bit IO Format: %lld & %llu |
Description
Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子
一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。
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
一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。
Input
输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。
Output
输出最长区域的长度。
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
Source