[BZOJ1616][Usaco2008 Mar]Cow Travelling游荡的奶牛(dfs||dp)

来源:互联网 发布:mac怎么下载crossover 编辑:程序博客网 时间:2024/05/22 16:16

题目描述

传送门

题解

看题了之后算了算,步数只有15步,似乎加了这个剪枝之后状态很少啊= =于是直接开始码bfs。码出来了之后发现对拍大数据老是出错,而且把剪枝加的越少数越小!原来我忽略了一个非常重要的问题:队列空间!!!虽然是循环队列,但是由于同时入队的元素非常多,有可能把很多有用的状态覆盖掉!
那么bfs就没法写了,不过dfs是资瓷的,因为递归层数最多是15.不过这道题其实是一道非常简单的dp,设f(i,j,k)表示第i步走到第(j,k)个格子时的方案数,然后就可以递推了。如果丧心病狂一点卡卡内存什么的还可以用滚动优化。

代码

dfs

#include<iostream>#include<cstring>#include<cstdio>#include<queue>using namespace std;#define N 105int n,m,T,sx,sy,tx,ty,ans;char squ[N][N],s[N];int dx[4]={0,0,-1,1};int dy[4]={1,-1,0,0};int Abs(int x){    return (x>0)?x:-x;}void dfs(int x,int y,int dep){    if (x==tx&&y==ty&&dep==T)    {        ans++;        return;    }    if (dep==T) return;    for (int i=0;i<4;++i)    {        int xx=x+dx[i],yy=y+dy[i];        if (xx<1||xx>n||yy<1||yy>m||squ[xx][yy]=='*') continue;        if (dep+1+Abs(tx-xx)+Abs(ty-yy)>T) continue;        if (dep+1<=T) dfs(xx,yy,dep+1);    }}int main(){    scanf("%d%d%d\n",&n,&m,&T);    for (int i=1;i<=n;++i)    {        gets(s);        for (int j=1;j<=m;++j) squ[i][j]=s[j-1];    }    scanf("%d%d%d%d",&sx,&sy,&tx,&ty);    if (squ[sx][sy]=='*'||squ[tx][ty]=='*')    {        puts("0");        return 0;    }    dfs(sx,sy,0);    printf("%d\n",ans);}

dp

#include<iostream>#include<cstring>#include<cstdio>#include<queue>using namespace std;#define N 105int n,m,T,sx,sy,tx,ty;char squ[N][N],s[N];int dx[4]={0,0,-1,1};int dy[4]={1,-1,0,0};int f[20][N][N];int main(){    scanf("%d%d%d\n",&n,&m,&T);    for (int i=1;i<=n;++i)    {        gets(s);        for (int j=1;j<=m;++j) squ[i][j]=s[j-1];    }    scanf("%d%d%d%d",&sx,&sy,&tx,&ty);    if (squ[sx][sy]=='*'||squ[tx][ty]=='*')    {        puts("0");        return 0;    }    f[0][sx][sy]=1;    for (int i=1;i<=T;++i)    {        for (int j=1;j<=n;++j)            for (int k=1;k<=m;++k)            {                if (squ[j][k]=='*') continue;                for (int l=0;l<4;++l)                {                    int x=j+dx[l],y=k+dy[l];                    if (x<1||x>n||y<1||y>m||squ[x][y]=='*') continue;                    f[i][j][k]+=f[i-1][x][y];                }            }    }    printf("%d\n",f[T][tx][ty]);}

总结

①有关于“步数”的bfs原来还可以向dp转化!并且状态之和上一维相关。

0 0
原创粉丝点击