滑雪(ski)
滑雪(ski)
题目描述
Michael喜欢滑雪。这并不奇怪,因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道在一个区域中最长的滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。
输入
第1行为表示区域的二维数组的行数R和列数C(1≤R,C≤l00)。下面是R行,每行有C个数,代表高度。
输出
输出区域中最长滑坡的长度。
样例输入
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
提示
一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可行的滑坡为24-17-16-1(从24开始,在l结束)。当然25-24-23-…-3-2-1更长。事实上,这是最长的一条。
分析:可以按权值从小到大遍历点(贪心),另一种思路是直接记忆化,貌似记忆化更快。。。
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <map> #include <queue> #include <stack> #include <vector> #include <list> #include <ext/rope> #define rep(i,m,n) for(i=m;i<=n;i++) #define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++) #define vi vector<int> #define pii pair<int,int> #define mod 1000000007 #define inf 0x3f3f3f3f #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) const int maxn=1e2+10; const int dis[4][2]={{0,1},{-1,0},{0,-1},{1,0}}; using namespace std; using namespace __gnu_cxx; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;} int n,m,a[maxn][maxn],ma,vis[maxn][maxn]; set<pair<int,pii> >q; int main() { int i,j,k,t; scanf("%d%d",&n,&m); rep(i,0,n-1)rep(j,0,m-1)scanf("%d",&a[i][j]),q.insert(mp(a[i][j],mp(i,j))); for(auto x:q) { int val=x.fi,l=x.se.fi,r=x.se.se; vis[l][r]=1; for(int i=0;i<4;i++) { int xx=l+dis[i][0],yy=r+dis[i][1]; if(xx>=0&&xx<n&&yy>=0&&yy<m&&vis[xx][yy]&&a[xx][yy]<a[l][r]) { vis[l][r]=max(vis[l][r],vis[xx][yy]+1); } } ma=max(ma,vis[l][r]); } printf("%d\n",ma); //system ("pause"); return 0; }
记忆化:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <cstring> #include <stack> #include <cctype> #include <queue> #include <string> #include <vector> #include<functional> #include <set> #include <map> #include <climits> #define lson root<<1,l,mid #define rson root<<1|1,mid+1,r #define fi first #define se second #define ping(x,y) ((x-y)*(x-y)) #define mst(x,y) memset(x,y,sizeof(x)) #define mcp(x,y) memcpy(x,y,sizeof(y)) using namespace std; #define gamma 0.5772156649015328606065120 #define MOD 1000000007 #define inf 0x3f3f3f3f #define N 30005 #define maxn 100005 typedef pair<int,int> PII; typedef long long LL; int n,m; int dp[105][105]; int a[105][105]; int dir[][2]={{1,0},{-1,0},{0,1},{0,-1}}; int dfs(int x,int y){ if(dp[x][y]!=-1)return dp[x][y]; for(int i=0;i<4;++i){ int xx=x+dir[i][0]; int yy=y+dir[i][1]; if(xx<1||xx>n||yy<1||yy>m)continue; if(a[xx][yy]<a[x][y]){ dp[x][y]=max(dp[x][y],1+dfs(xx,yy)); } } return dp[x][y]=max(dp[x][y],1); } int main(){ //freopen("in.txt","r",stdin); int i,j; while(scanf("%d%d",&n,&m)!=EOF){ for(i=1;i<=n;++i) for(j=1;j<=m;++j) scanf("%d",&a[i][j]); mst(dp,-1); for(i=1;i<=n;++i)for(j=1;j<=m;++j)if(dp[i][j]==-1)dp[i][j]=dfs(i,j); int ans=-1; for(i=1;i<=n;++i)for(j=1;j<=m;++j)ans=max(ans,dp[i][j]); printf("%d\n",ans); } return 0; }