skiing 【DP】

来源:互联网 发布:如何找到淘宝套现商家 编辑:程序博客网 时间:2024/06/16 14:45

skiing

时间限制:3000 ms  |  内存限制:65535 KB
难度:5
描述
Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子 
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更长。事实上,这是最长的一条。
输入
第一行表示有几组测试数据,输入的第二行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。
后面是下一组数据;
输出
输出最长区域的长度。
样例输入
15 51 2 3 4 516 17 18 19 615 24 25 20 714 23 22 21 813 12 11 10 9
样例输出
25
来源
经典题目
上传者

iphxer


思路: 看着 分类为dp。 本着不熟的dp思想,硬是编了个像dp的东西。。 没想到还是超时,,,,(写的很复杂,想着都不会过。。)

 结果就换了个 dfs 看能不能成,,一下就ac了。。。。0.0  


我的 dp 错误代码

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<stack>
#include<queue>
#define inf 0x3f3f3f
#define M 100+10
using namespace std;
int map[M][M];
int dp[M][M];
int to[4][2]={1,0,-1,0,0,1,0,-1};
int main()
{
  int n;
  scanf("%d",&n);
  while(n--)
  {
  int row,lie;
  scanf("%d%d",&row,&lie);
 
  memset(map,0,sizeof(map));
  for(int i=1;i<=row;i++)
  {
  for(int j=1;j<=lie;j++)
  {
  scanf("%d",&map[i][j]);
  dp[i][j]=1;
 }
 
  int max=0;
  for(int u=1;u<500;u++)  // 这个u要很大才可以,,就是要dp遍历好几遍才可以得到最大的 
  {
 
  for(int i=1;i<=row;i++)//dp 
  {
  for(int j=1;j<=lie;j++)
  {
  for(int k=0;k<4;k++)
  {
  int ni=i+to[k][0];
  int nj=j+to[k][1];
  if(map[i][j]<map[ni][nj]&&dp[i][j]<dp[ni][nj]+1)
  {
  dp[i][j]=dp[ni][nj]+1;
  if(max<dp[i][j]) max=dp[i][j];
 }
 }
 }
  }
 }
  printf("%d\n",max);
}
return 0;
 } 



 dfs   ac代码 

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<stack>
#include<queue>
#define inf 0x3f3f3f
#define M 100+10
using namespace std;
int row,lie;
int map[M][M];
int num;
int to[4][2]={0,1,0,-1,-1,0,1,0};
void dfs(int x,int y,int step)
{
if(step>num) num=step; //  找出 每一次dfs中最长的路径 
for(int k=0;k<4;k++)
{
int nx=x+to[k][0];
int ny=y+to[k][1];
if(map[nx][ny]&&map[nx][ny]<map[x][y])
{
dfs(nx,ny,step+1);
}
}
}
int main()
{
int  n;
scanf("%d",&n);
while(n--)
{
scanf("%d%d",&row,&lie);
memset(map,0,sizeof(map));
for(int i=1;i<=row;i++)
{
for(int j=1;j<=lie;j++)
scanf("%d",&map[i][j]);
}
int maxx=0;num=0;
for(int i=1;i<=row;i++)
{
for(int j=1;j<=lie;j++)   //  由于起点不同,每个dfs的结果不一样,,这个时候再找出 这些中的最大就可以了
{
dfs(i,j,0);
if(num>maxx) maxx=num;   //  获得 所有dfs中的最大值
}
}
printf("%d\n",maxx+1);
}
return 0;
}



网上找的dp解 (看了之后有点凌乱)

  1. #include<cstdio>  
  2. #include<iostream>  
  3. #include<cstring>  
  4. #include<cstdlib>  
  5. using namespace std;  
  6.   
  7. const int MAXN =  100+5;  
  8. int G[MAXN][MAXN][4];  
  9. int d[MAXN][MAXN];  
  10. int a[MAXN][MAXN];  
  11.   
  12. int max(int a, int b){  
  13.     if(a>b) return a;  
  14.     else    return b;  
  15. }   
  16.   
  17. int dp(int i, int j, int r, int c){  
  18.     int& ans = d[i][j];  
  19.     if(ans>0) return ans;  
  20.     ans = 1;   
  21.     if((i-1>=0)   && G[i][j][0])  ans = max(ans, dp(i-1, j, r, c)+1);  //向上   
  22.     if((i+1<=r-1) && G[i][j][2])  ans = max(ans, dp(i+1, j, r, c)+1);  //向下   
  23.     if((j-1>=0)   && G[i][j][3])  ans = max(ans, dp(i, j-1, r, c)+1);  //向左   
  24.     if((j+1<=c-1) && G[i][j][1])  ans = max(ans, dp(i, j+1, r, c)+1); //向右   
  25.     return ans;  
  26. }  
  27. int _G(int r, int c) {  //存图时,每个点数据都已经事先存储好了   
  28.     for(int i = 0; i < r; i++){  
  29.         for(int j = 0; j < c; j++){  
  30.             if((i-1>=0)   && a[i][j]>a[i-1][j]) G[i][j][0] = 1;  //向上   
  31.             if((i+1<=r-1) && a[i][j]>a[i+1][j]) G[i][j][2] = 1;  //向下   
  32.             if((j-1>=0)   && a[i][j]>a[i][j-1]) G[i][j][3] = 1;  //向左   
  33.             if((j+1<=c-1) && a[i][j]>a[i][j+1]) G[i][j][1] = 1; //向右   
  34.         }  
  35.     }  
  36. }  
  37. void init(){  
  38.     memset(G, 0, sizeof(G));  
  39.     memset(d, 0, sizeof(d));  
  40.     memset(a, 0, sizeof(a));  
  41. }  
  42. /* 
  43. void print_map(int r, int c){  //打印存图  
  44.     for(int i = 0; i < r; i++){ 
  45.         for(int j = 0; j < c; j++){ 
  46.             printf("(%d,%d,%d,%d) ", G[i][j][0], G[i][j][1], G[i][j][2], G[i][j][3]);  //括号中的顺序代表上右下左分别是否能走通  
  47.         } 
  48.         printf("\n"); 
  49.     } 
  50.  
  51. */  
  52. int main(){  
  53.     int T;  
  54.     scanf("%d", &T);  
  55.     while(T--){  
  56.         int r, c;  
  57.         scanf("%d%d",&r, &c);  
  58.         init();  
  59.         for(int i = 0; i < r; i++){//存储点  
  60.             for(int j = 0; j < c; j++) {  
  61.                 scanf("%d", &a[i][j]);  
  62.             }  
  63.         }  
  64.           
  65.         _G(r,c);//存图   
  66.           
  67.         int ans = 0;   
  68.         for(int i = 0; i < r; i++){  
  69.             for(int j = 0; j < c; j++) {  
  70.                 ans = max(ans, dp(i, j, r, c));  
  71.             }  
  72.         }  
  73.           
  74.         printf("%d\n", ans);  
  75.     //  print_map(r, c);   
  76.     }  
  77.     return 0;  
  78. }  

0 0
原创粉丝点击