358 条题解
-
0钱思远 LV 9 @ 2015-05-28 20:22:07
应该就是个搜索吧!
-
02015-05-09 15:36:07@
#include<cstdio>
#include<cstring>
const int dx[4]={-1,0,1,0};//定义四种滑雪规则
const int dy[4]={0,-1,0,1};
int m[502][502];
int f[502][502];
int r,c;
int search(int x,int y)
{
if (f[x][y]){//说明f[i][j]的最大距离已经确定
return f[x][y];
}
int t=1;
for (int i=0;i<4;i++)
{
int nx=x+dx[i];//nx,ny为移动后的坐标
int ny=y+dy[i];
if(nx<=r&&nx>=1&&ny<=c&&ny>=1&&m[x][y]<m[nx][ny])
{//判断边界+比较高度
int tmp=search(nx,ny)+1;
if (tmp>t) t=tmp;//向上下左右搜找到一个最大值
}
}
f[x][y]=t;//赋值,把搜索的值存下来,以便下次调用
return t;
}
int main()
{
memset(m,0xff,sizeof(m));
scanf("%d%d",&r,&c);
for (int i=1;i<=r;i++)
for (int j=1;j<=c;j++)
scanf("%d",&m[i][j]);
int ans=0;
for (int i=1;i<=r;i++)
for (int j=1;j<=c;j++)
{
f[i][j]=search(i,j);
ans=f[i][j]>ans?f[i][j]:ans;
}
printf("%d\n",ans);
return 0;
} -
02015-02-05 16:41:11@
备忘录方法处理起来比较容易,动态规划描述起来比较复杂。
#include<iostream>
#include<string.h>
#include<math.h>
#include<stdio.h>
using namespace std;
int a[505][505];
int ans[505][505];
int xsize, ysize;
int f(int x, int y){
if (x < 0 || y < 0)return 0;
if (x >= xsize || y>=ysize)return 0;
if (ans[x][y] == -1){
ans[x][y] = 0;
if (a[x][y]>a[x - 1][y])ans[x][y] = f(x-1,y);
if (a[x][y]>a[x + 1][y] && ans[x][y] < f(x + 1, y))
ans[x][y] = f(x + 1, y) ;
if (a[x][y]>a[x][y - 1] && ans[x][y] < f(x, y - 1))
ans[x][y] = f(x, y - 1) ;
if (a[x][y]>a[x][y + 1] && ans[x][y] < f(x, y + 1) )
ans[x][y] = f(x, y + 1) ;
ans[x][y]++;
}
return ans[x][y];
}
int main(){
freopen("in.txt", "r", stdin);
cin >> xsize >> ysize;
memset(ans, -1, sizeof(ans));
int i, j;
for (i = 0; i < xsize; i++){
for (j = 0; j < ysize; j++){
cin >> a[i][j];
}
}
int ma=0;
for (i = 0; i < xsize; i++){
for (j = 0; j < ysize; j++){
if (ma < f(i, j))ma = f(i, j);
}
}
cout << ma << endl;
return 0;
} -
02015-02-05 10:21:52@
-
02015-01-08 21:38:54@
评测结果
编译成功测试数据 #0: Accepted, time = 89 ms, mem = 2700 KiB, score = 10
测试数据 #1: Accepted, time = 15 ms, mem = 2700 KiB, score = 10
测试数据 #2: Accepted, time = 39 ms, mem = 2696 KiB, score = 10
测试数据 #3: Accepted, time = 15 ms, mem = 2700 KiB, score = 10
测试数据 #4: Accepted, time = 62 ms, mem = 2700 KiB, score = 10
测试数据 #5: Accepted, time = 7 ms, mem = 2700 KiB, score = 10
测试数据 #6: Accepted, time = 15 ms, mem = 2700 KiB, score = 10
测试数据 #7: Accepted, time = 31 ms, mem = 2700 KiB, score = 10
测试数据 #8: Accepted, time = 15 ms, mem = 2700 KiB, score = 10
测试数据 #9: Accepted, time = 46 ms, mem = 2696 KiB, score = 10
Accepted, time = 334 ms, mem = 2700 KiB, score = 100####**代码**
program skiing;
var
a,f:array[0..500,0..500] of longint;
i,j,r,c,ans:longint;
function dp(x,y:longint):longint;
var
w:longint;
begin
if f[x,y]<>0 then exit(f[x,y]);
if (x>1) and (a[x,y]>a[x-1,y]) then
begin
w:=dp(x-1,y);
if w>f[x,y] then f[x,y]:=w;
end;
if (y>1) and (a[x,y]>a[x,y-1]) then
begin
w:=dp(x,y-1);
if w>f[x,y] then f[x,y]:=w;
end;
if (x<r) and (a[x,y]>a[x+1,y]) then
begin
w:=dp(x+1,y);
if w>f[x,y] then f[x,y]:=w;
end;
if (y<c) and (a[x,y]>a[x,y+1]) then
begin
w:=dp(x,y+1);
if w>f[x,y] then f[x,y]:=w;
end;
f[x,y]:=f[x,y]+1;dp:=f[x,y];
end;
begin
readln(r,c);
for i:=1 to r do for j:=1 to c do read(a[i,j]);
fillchar(f,sizeof(f),0);
ans:=0;
for i:=1 to r do
for j:=1 to c do
if ans<dp(i,j) then ans:=dp(i,j);
writeln(ans);
end.在多年的迷茫后,我终于发现了方向。
原来后效性是可以用递归消除的……
辅之以记忆化搜索后速度也很快……规定
f[i,j]
为(i,j)点开始的最长路线,则f[i,j]=max{f[i-1,j],f[i,j-1],f[i+1,j],f[i,j+1]}+1
-
02015-01-05 22:59:00@
题目数据范围有误!!!
说好的h<=10000呢,实际第9个点有数据大于30000!让我这直接桶排的情何以堪!!调了2个小时!最后发现数据改为50000的桶排就能过了。。。。#include<stdio.h>
int a[260000],b[600][600],d[600][600],x[260001],y[260001],g[50011],g1[50011];int main()
{
int r,c,i,j,min,max,t,x1[5]={0,0,-1,0,1},y1[5]={0,1,0,-1,0};
scanf("%d%d",&r,&c);
for (i=0;i<=r+1;i++)
for (j=0;j<=c+1;j++)
{d[i][j]=-10;b[i][j]=1;}
for (i=-1;i<=50000;i++) {g[i]=0;g1[i]=0;}
for (i=1;i<=r;i++)
for (j=1;j<=c;j++)
{
scanf("%d",&d[i][j]);
g1[d[i][j]]++;
}
for (i=1;i<=50000;i++) g1[i]+=g1[i-1];
for (i=1;i<=r;i++)
for (j=1;j<=c;j++)
{g[d[i][j]]++;
x[g[d[i][j]]+g1[d[i][j]-1]]=i;
y[g[d[i][j]]+g1[d[i][j]-1]]=j;
}
for (t=1;t<=r*c;t++)
for (i=1;i<=4;i++)
if (d[x[t]+x1[i]][y[t]+y1[i]]>d[x[t]][y[t]]&&b[x[t]][y[t]]+1>b[x[t]+x1[i]][y[t]+y1[i]])
b[x[t]+x1[i]][y[t]+y1[i]]=b[x[t]][y[t]]+1;
max=0;
for (i=1;i<=r;i++)
for (j=1;j<=c;j++)
if (b[i][j]>max) max=b[i][j];
printf("%d",max);
return 0;
} -
02014-11-28 00:24:00@
为何楼下仁兄都说要排序?不需要吧!见楼下↓没用排序哦
-
02014-11-28 00:22:41@
诡异的速度,简单的代码尽在这里;
http://blog.csdn.net/u012746396/article/details/41560299
欢迎支持!
您的支持就是我的进步 -
02014-11-04 15:31:45@
测试数据 #0: Accepted, time = 234 ms, mem = 5252 KiB, score = 10
测试数据 #1: Accepted, time = 31 ms, mem = 5252 KiB, score = 10
测试数据 #2: Accepted, time = 62 ms, mem = 5256 KiB, score = 10
测试数据 #3: Accepted, time = 0 ms, mem = 5252 KiB, score = 10
测试数据 #4: Accepted, time = 140 ms, mem = 5256 KiB, score = 10
测试数据 #5: Accepted, time = 15 ms, mem = 5252 KiB, score = 10
测试数据 #6: Accepted, time = 15 ms, mem = 5248 KiB, score = 10
测试数据 #7: Accepted, time = 78 ms, mem = 5252 KiB, score = 10
测试数据 #8: TimeLimitExceeded, time = 2031 ms, mem = 5252 KiB, score = 0
测试数据 #9: Accepted, time = 109 ms, mem = 5252 KiB, score = 10
TimeLimitExceeded, time = 2715 ms, mem = 5256 KiB, score = 90
代码
var
h:array[1..520,1..520]of integer;
m:array[1..520,1..520]of longint;
tmp,xx,yy:array[1..250020]of longint;
r,c,i,j,t,max:longint;
function maxx(a,b:longint):longint;
begin if a>b then exit(a) else exit(b); end;
procedure qs(x,y:longint);
var
l,r,mid,tt:longint;
begin
l:=x; r:=y; mid:=tmp[(l+r) div 2];
repeat
while tmp[l]>mid do inc(l);
while tmp[r]<mid do dec(r);
if l<=r then begin tt:=tmp[l]; tmp[l]:=tmp[r]; tmp[r]:=tt;
tt:=xx[l]; xx[l]:=xx[r]; xx[r]:=tt;
tt:=yy[l]; yy[l]:=yy[r]; yy[r]:=tt;
inc(l); dec(r); end;
until l>r;
if r>x then qs(x,r);
if l<y then qs(l,y);
end;
function dfs(x,y:longint):longint;
var i,j:longint;
begin
if m[x,y]<>0 then exit(m[x,y]);
dfs:=1;
if (x-1>0) and (h[x-1,y]<h[x,y]) then dfs:=maxx(dfs(x-1,y)+1,dfs);
if (x+1<=r) and (h[x+1,y]<h[x,y]) then dfs:=maxx(dfs(x+1,y)+1,dfs);
if (y-1>0) and (h[x,y-1]<h[x,y]) then dfs:=maxx(dfs(x,y-1)+1,dfs);
if (y+1<=c) and (h[x,y+1]<h[x,y]) then dfs:=maxx(dfs(x,y+1)+1,dfs);
end;
procedure init;
var
i,j:longint;
begin
readln(r,c);
for i:=1 to r do
for j:=1 to c do
read(h[i,j]);
t:=0;
for i:=1 to r do
for j:=1 to c do
begin inc(t); tmp[t]:=h[i,j]; xx[t]:=i; yy[t]:=j; end;
qs(1,t);
for i:=1 to t do
begin
m[xx[i],yy[i]]:=dfs(xx[i],yy[i]);
end;
max:=0;
for i:=1 to r do
for j:=1 to c do
if m[i,j]>max then max:=m[i,j];
writeln(max);
end;
begin
init;
我用的记忆化搜索(DP)为什么第9个点TLE啊
end. -
02014-08-19 15:08:57@
测试数据 #0: Accepted, time = 156 ms, mem = 5380 KiB, score = 10
测试数据 #1: Accepted, time = 31 ms, mem = 5380 KiB, score = 10
测试数据 #2: Accepted, time = 46 ms, mem = 5384 KiB, score = 10
测试数据 #3: Accepted, time = 0 ms, mem = 5376 KiB, score = 10
测试数据 #4: Accepted, time = 93 ms, mem = 5384 KiB, score = 10
测试数据 #5: Accepted, time = 0 ms, mem = 5380 KiB, score = 10
测试数据 #6: Accepted, time = 15 ms, mem = 5380 KiB, score = 10
测试数据 #7: Accepted, time = 62 ms, mem = 5384 KiB, score = 10
测试数据 #8: Accepted, time = 15 ms, mem = 5380 KiB, score = 10
测试数据 #9: Accepted, time = 78 ms, mem = 5380 KiB, score = 10
一遍AC真爽,思路大致就是排序,然后dp一下就好了,include <stdio.h>
include <string.h>
include <stdlib.h>
define max(a,b) (a > b) ? a : b
typedef struct{
int a;
int b;
int key;} no;
int q[501][501],d[501][501];
no s[250001];
int cmp(const void *a,const void b)
{return ((no )a).key - ((no *)b).key;}
int main()
{
int i,j,k,l,x,y,t = 0,m,n,ans = 0;
scanf("%d%d",&m,&n);
for(i = 1;i <= m;i++)
for(j = 1;j <= n;j++)
{scanf("%d",&q[i][j]);
s[t].key = q[i][j];
s[t].a = i;
s[t++].b = j;
d[i][j] = 1;}
l = m * n;
qsort(s,l,sizeof(s[0]),cmp);
for(i = 0;i < l;i++)
{x =s[i].a;y = s[i].b;
if(x-1 > 0 && q[x-1][y] < q[x][y]) d[x][y] = max(d[x-1][y]+1,d[x][y]);
if(y-1 > 0 && q[x][y-1] < q[x][y]) d[x][y] = max(d[x][y-1]+1,d[x][y]);
if(y+1 <= n && q[x][y+1] < q[x][y]) d[x][y] = max(d[x][y+1]+1,d[x][y]);
if(x+1 <= m && q[x+1][y] < q[x][y]) d[x][y] = max(d[x+1][y]+1,d[x][y]);
ans = max(ans,d[x][y]);}
printf("%d\n",ans);
} -
02014-01-14 08:17:06@
-
02013-12-15 16:17:27@
编译成功
foo.pas(31,16) Warning: Variable "ans" does not seem to be initialized
测试数据 #0: Accepted, time = 93 ms, mem = 2696 KiB, score = 10
测试数据 #1: Accepted, time = 15 ms, mem = 2696 KiB, score = 10
测试数据 #2: Accepted, time = 31 ms, mem = 2696 KiB, score = 10
测试数据 #3: Accepted, time = 0 ms, mem = 2696 KiB, score = 10
测试数据 #4: Accepted, time = 46 ms, mem = 2692 KiB, score = 10
测试数据 #5: Accepted, time = 0 ms, mem = 2696 KiB, score = 10
测试数据 #6: Accepted, time = 0 ms, mem = 2696 KiB, score = 10
测试数据 #7: Accepted, time = 31 ms, mem = 2696 KiB, score = 10
测试数据 #8: Accepted, time = 15 ms, mem = 2696 KiB, score = 10
测试数据 #9: Accepted, time = 62 ms, mem = 2696 KiB, score = 10
Accepted, time = 293 ms, mem = 2696 KiB, score = 100###记忆化搜索
const
dx:array[1..4]of integer=(-1,1,0,0);
dy:array[1..4]of integer=(0,0,-1,1);
var
h,dis:array[1..500,1..500]of longint;
i,j,n,m,ans:longint;
function search(x,y:longint):longint;
var
ans,i:longint;
begin
if dis[x,y]<>0 then exit(dis[x,y]);
dis[x,y]:=1; ans:=0;
for i:=1 to 4 do
if (x+dx[i]>0)and(x+dx[i]<=n)and(y+dy[i]>0)and(y+dy[i]<=m)
and(h[x+dx[i],y+dy[i]]<h[x,y])then
begin
ans:=search(x+dx[i],y+dy[i])+1;
if ans>dis[x,y]then dis[x,y]:=ans;
end;
exit(dis[x,y]);
end;
begin
readln(n,m);
for i:=1 to n do
for j:=1 to m do
read(h[i,j]);
for i:=1 to n do
for j:=1 to m do
begin
dis[i,j]:=search(i,j);
if dis[i,j]>ans then ans:=dis[i,j];
end;
write(ans);
end. -
02013-11-08 07:34:52@
首先快排一遍,从大的开始做,时间效率O(nlogn+n^2)
-
02013-11-01 15:58:56@
#include <iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
struct arr{int x,y,num;} list[1000000];
int map[1000][1000],f[1000][1000],u[]={1,-1,0,0},w[]={0,0,1,-1};
bool cmp(arr a,arr b){return a.num<b.num;}
int main()
{
int h,l,k=1,maxx=0;
scanf("%d%d",&h,&l);
for(int i=1;i<=h;i++) for(int j=1;j<=l;j++){
scanf("%d",&map[i][j]); list[k].num=map[i][j];
list[k].x=i; list[k].y=j; k++;
}
sort(list+1,list+k,cmp);
for(int i=k-1;i>=1;i--){
int x1=list[i].x,y1=list[i].y;
f[x1][y1]++;
for(int j=0;j<4;j++)
if(map[x1+u[j]][y1+w[j]]>map[x1][y1])
f[x1][y1]=max(f[x1][y1],f[x1+u[j]][y1+w[j]]+1);
maxx=max(maxx,f[x1][y1]);
}
printf("%d\n",maxx);
return 0;
} -
02013-10-15 20:18:19@
const dx:array[1..4] of integer=(-1,0,1,0);
dy:array[1..4] of integer=(0,-1,0,1);
var
n,m,l,r,k,i,j,ans:longint;
a,b:array[0..501,0..501] of longint;
procedure dfs(i,j:longint);
var k,l,x,y:longint;
begin
if b[i,j]>ans then ans:=b[i,j];
for k:=1 to 4 do
if (a[i+dx[k],j+dy[k]]>a[i,j])and(b[i,j]+1>b[i+dx[k],j+dy[k]]) then
begin b[i+dx[k],j+dy[k]]:=b[i,j]+1;dfs(i+dx[k],j+dy[k]); end;
end;
begin
readln(n,m);
for i:=1 to n do
for j:=1 to m do
read(a[i,j]);
for i:=1 to n do
for j:=1 to m do
begin
if b[i,j]=0 then begin b[i,j]:=1;dfs(i,j); end;
end;
writeln(ans);
end.刚开始把输入的m打成了n,提交了4遍,改了一个小时,无语了...
-
02013-08-31 14:05:35@
-
02013-07-29 18:05:14@
-
02013-07-11 09:55:03@
0-0
-
02013-07-11 09:54:27@
[url=www.baidu.com]呵呵[/url]
-
02013-06-21 13:58:05@
排序一下 然后DP就好了。。
评测结果
VijosEx via JudgeDaemon2/13.6.5.0 via libjudge
编译成功测试数据 #0: Accepted, time = 265 ms, mem = 5356 KiB, score = 10
测试数据 #1: Accepted, time = 31 ms, mem = 5352 KiB, score = 10
测试数据 #2: Accepted, time = 78 ms, mem = 5348 KiB, score = 10
测试数据 #3: Accepted, time = 0 ms, mem = 5348 KiB, score = 10
测试数据 #4: Accepted, time = 171 ms, mem = 5348 KiB, score = 10
测试数据 #5: Accepted, time = 15 ms, mem = 5348 KiB, score = 10
测试数据 #6: Accepted, time = 15 ms, mem = 5352 KiB, score = 10
测试数据 #7: Accepted, time = 109 ms, mem = 5348 KiB, score = 10
测试数据 #8: Accepted, time = 78 ms, mem = 5348 KiB, score = 10
测试数据 #9: Accepted, time = 187 ms, mem = 5352 KiB, score = 10
Accepted, time = 949 ms, mem = 5356 KiB, score = 100
#include <cstdio>
#include <algorithm>
#include <cstring>using namespace std;
#define MAXN 501
int f[MAXN][MAXN];
struct saver {
int x,y,h;
} nu[MAXN*MAXN];int h[MAXN][MAXN];
int n,m;
bool cmp(saver x,saver y){
return x.h>y.h;
}const int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int main(){
scanf("%d%d",&n,&m);
for (int i=0;i++<n;){
for (int j=0;j++<m;){
scanf("%d",&h[i][j]);
nu[(i-1)*m+j-1].x=i;
nu[(i-1)*m+j-1].y=j;
nu[(i-1)*m+j-1].h=h[i][j];
}
}
sort(nu,nu+(m*n),cmp);
memset(f,0,sizeof(f));
for (int i=0;i<n*m;i++){
f[nu[i].x][nu[i].y]=max(f[nu[i].x][nu[i].y],1);
int x0=nu[i].x,y0=nu[i].y;
for (int j=0;j<4;j++){
if (x0+d[j][0]>0&&x0+d[j][0]<=n&&y0+d[j][1]>0&&y0+d[j][1]<=m){
if (h[x0+d[j][0]][y0+d[j][1]]<nu[i].h){
f[x0+d[j][0]][y0+d[j][1]]=max(f[x0+d[j][0]][y0+d[j][1]],f[nu[i].x][nu[i].y]+1);
}
}
}
}
int ans=0;
for (int i=0;i++<n;){
for (int j=0;j++<m;){
ans=max(ans,f[i][j]);
}
}
printf("%d\n",ans);
return 0;
}