题意:一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。
思路:动态规划。正向递推和递归(记忆化搜索)方式都可以。用递推时注意需要将高度排序。需要注意一个细节,如果一个位置比它四周的位置都低,那么它的高度为1,而不是0.
递推:
#include
#include
#include
#include
#include
#include
#include
#define INF 0x3fffffff
using namespace std;
#define N 105
int dp[N][N],s[N][N];
struct point{
int x,y,h;
}p[N*N];
int n,m,top = 0;
int ori[4][2] = {{-1,0},{1,0},{0,1},{0,-1}};
int cmp(struct point a,struct point b){
return a.h < b.h;
}
int main(){
int i,j,x,y,res=0;
scanf("%d %d",&n,&m);
memset(dp,0,sizeof(dp));
memset(s, 0, sizeof(s));
for(i = 1;i<=n;i++)
for(j = 1;j<=m;j++){
scanf("%d",&s[i][j]);
p[top].x = i;
p[top].y = j;
p[top++].h = s[i][j];
}
sort(p,p+top,cmp);
for(i = 0;i s[x+ori[j][0]][y+ori[j][1]])
dp[x][y] = max(dp[x][y],dp[x+ori[j][0]][y+ori[j][1]]+1);
res = max(res,dp[x][y]);
}
printf("%d\n",res);
return 0;
}
#include
#include
#define M 105
int flag[M][M];
int s[M][M];
int m,n;
int around[4][2] = {-1,0,0,-1,1,0,0,1};
int Max(int a,int b){
return as[xx][yy])
height = Max(dp(xx,yy),height);
}
return flag[x][y] = height+1;
}
int main(){
int i,j,max;
scanf("%d %d",&n,&m);
memset(flag,0,sizeof(flag));
memset(s,0,sizeof(s));
for(i = 1;i<=n;i++)
for(j = 1;j<=m;j++)
scanf("%d",&s[i][j]);
for(i = 1;i<=n;i++)
for(j = 1;j<=n;j++)
dp(i,j);
for(max = 0,i = 1;i<=n;i++)
for(j = 1;j<=m;j++)
if(flag[i][j] > max)
max = flag[i][j];
printf("%d\n",max);
return 0;
}
2111:题意与1088的区别:不是从高到低,而是从低到高爬坡;爬坡不是向四周,而是走“日”(象棋中的马走日);输出要求按照序列的字典序输出。
思路:仍然是dp没的说,需要考虑怎么输出。一开始怎么也转不过这个弯,认为从低到高更新,那么考虑字典序需要追溯到路径的开始才能比较。后来知道还是从高到低更新即可,这样自然保证了字典序。
#include
#include
#include
#include
#include
#include
using namespace std;
#define INF 0x3fffffff
#define clr(s,t) memset(s,t,sizeof(s))
#define N 365
int s[N][N],dp[N][N],pre[N][N],n,len;
struct node{
int x,y,h;
}p[N*N];
int ori[8][2] = {{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2}};
int cmp(node a,node b){
return a.h > b.h;
}
int check(int x,int y){
return x>=1&&y>=1&&x<=n&&y<=n;
}
int main(){
int i,j,k,x,y;
len = 0;
clr(dp, 0);
clr(pre, 0);
scanf("%d",&n);
for(i = 1;i<=n;i++)
for(j = 1;j<=n;j++){
scanf("%d",&s[i][j]);
p[len].x = i;
p[len].y = j;
p[len++].h = s[i][j];
}
sort(p,p+len,cmp);//按照高度从高到低排序
for(i = 0;ik ||(dp[i][j]==k&&s[i][j]