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;
    }
  • 相关阅读:
    Java创建和解析Json对象
    Tyche 2191 WYF的递推式
    Tyche 2147 旅行
    Tyche 2317 Color
    洛谷 P1092 虫食算
    洛谷 P3951 小凯的疑惑
    BZOJ 1800 [Ahoi2009]fly 飞行棋
    BZOJ 1034 [ZJOI2008]泡泡堂BNB
    洛谷 P2151 [SDOI2009]HH去散步
    Android开发环境配置
  • 原文地址:https://www.cnblogs.com/ivanovcraft/p/9160658.html
Copyright © 2011-2022 走看看