zoukankan      html  css  js  c++  java
  • Luogu P1535 【游荡的奶牛】

    搜索
    不知道为什么没有人写bfs
    觉得挺像是标准个bfs的


    状态
    因为要统计次数,不能简单地跳过一个被经过的点
    这样的话,状态量会爆炸
    采用记忆化
    设dp[i][j][k]表示在第k分钟到达点(i,j)的方案数
    以地点+时间作为状态
    避免同一状态被反复拓展
    这样,状态量将减少至最多100*100*15


    转移
    这就比较显然了
    对于将被拓展的状态,在计数时加上当前状态的方案数
    如果这个状态曾被拓展,就不要别的操作了
    否则,将这一状态入队,预备拓展其他状态


    代码是这样的:

    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    struct node{
        int x,y,s;    //x、y表示坐标,s表示时间
    };
    queue<node>q;
    int n,m,t,r1,c1,r2,c2,dp[110][110][20];
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};    //移动
    string s[110];
    int main()
    {
        cin>>n>>m>>t;
        for(int i=1;i<=n;i++)
            cin>>s[i];
        cin>>r1>>c1>>r2>>c2;
        dp[r1][c1][0]=1;    //初始方案数为1
        q.push(node{r1,c1,0});
        while(!q.empty())
        {
            node u=q.front();
            q.pop();
            for(int i=0;i<4;i++)
            {
                node th;
                th.x=u.x+dx[i];
                th.y=u.y+dy[i];
                th.s=u.s+1;
                if(dp[th.x][th.y][th.s])
                {
                    dp[th.x][th.y][th.s]+=dp[u.x][u.y][u.s];
                    continue;    //当前状态曾被拓展
                }
                if(th.x<1||th.x>n||th.y<1||th.y>m||s[th.x][th.y-1]=='*'||th.s>t)
                    continue;    //越界或不能走或超时,跳过
                dp[th.x][th.y][th.s]+=dp[u.x][u.y][u.s];    //计数
                q.push(th);
            }
        }
        cout<<dp[r2][c2][t]<<endl;
        return 0;
    }
  • 相关阅读:
    hadoop的文件系统FileSystem
    关于hadoop的日志
    top命令的使用
    对于多个集合求两两交集(共同关注的用户、共同转载的微薄等)
    hadoop配置含义(继续更新中)
    thrift
    【VS2015】Win7 X64上面安装VS2015
    【经验记录】开发中的实际问题记录
    【VS2012】F5不能自动编译新修改
    斯巴达三百程序员
  • 原文地址:https://www.cnblogs.com/ivanovcraft/p/9160658.html
Copyright © 2011-2022 走看看