POJ - 1088 滑雪(DP/记忆化搜索)

#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

 Status

Description

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更长。事实上,这是最长的一条。

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



Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值