358 条题解

  • 0
    @ 2015-05-28 20:22:07

    应该就是个搜索吧!

  • 0
    @ 2015-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;
    }

  • 0
    @ 2015-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;
    }

  • 0
    @ 2015-02-05 10:21:52
  • 0
    @ 2015-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

  • 0
    @ 2015-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;
    }

  • 0
    @ 2014-11-28 00:24:00

    为何楼下仁兄都说要排序?不需要吧!见楼下↓没用排序哦

  • 0
    @ 2014-11-28 00:22:41

    诡异的速度,简单的代码尽在这里;
    http://blog.csdn.net/u012746396/article/details/41560299
    欢迎支持!
    您的支持就是我的进步

  • 0
    @ 2014-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.

  • 0
    @ 2014-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);
    }

  • 0
    @ 2013-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.

  • 0
    @ 2013-11-08 07:34:52

    首先快排一遍,从大的开始做,时间效率O(nlogn+n^2)

  • 0
    @ 2013-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;
    }

  • 0
    @ 2013-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遍,改了一个小时,无语了...

  • 0
    @ 2013-08-31 14:05:35
  • 0
    @ 2013-07-29 18:05:14
  • 0
    @ 2013-07-11 09:55:03

    0-0

  • 0
    @ 2013-07-11 09:54:27
  • 0
    @ 2013-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;
    }

信息

ID
1011
难度
6
分类
动态规划 点击显示
标签
递交数
10332
已通过
2936
通过率
28%
被复制
23
上传者