207. Course Schedule&576. Out of Boundary Paths

题目:There are a total of n courses you have to take, labeled from 0 to n - 1.

Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?

有n门课程需要选修,选修有些课程需要之前选修其他课程,比如选修课程0之前需要选修课程1,用[0,1]记录,给出所有选修对,看看是否能选修所有课程。

题意:选修课程A,要看看需要先选修哪些课程,接着看选修这些课程要选修哪些另外的课程。如果最后能找到不需要选修其他课程就能直接选修的课程,那么最后就能选修课程A,如果之前的课程都需要选修其他课程,那么就不能选修到课程A。如果把课程看成节点,选修对看成边,放在图论里,就是判断这个图有没有环,有环的话就选修失败。理解题意之后,这道题就迎刃而解了。用邻接表存储矩阵,从每个节点开始搜索判断有没有环,有环就return false,搜索所有的节点都没有环的话,就return true。搜索的时候,用一个数组记录节点是否搜索过,如果没有的话标记搜索过,并对这个节点深搜,搜索所有与之直接相邻的节点,重复上面的工作,如果发现相邻的节点已经搜索过了,说明存在环,return true。回溯退出的时候把节点标记未搜索过。


class Solution {
public:
    bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
        vector<vector<int>> Graph(numCourses);
        for(int i = 0; i < prerequisites.size(); ++i)
        {
            Graph[prerequisites[i].first].push_back(prerequisites[i].second);
        }
        for(int i = 0; i < numCourses; ++i)
        {
                vector<bool> isVisit(numCourses, 0);
                if(dfs(Graph, i, isVisit))
                    return false;
        }
        return true;
    }
    bool dfs(vector<vector<int>> &Graph, int start, vector<bool>& isVisit)
    {
        isVisit[start] = true;
        for(int i = 0; i < Graph[start].size(); ++i)
        {
            int next = Graph[start][i];
            if(isVisit[next] == true)
                return true;
            else if(dfs(Graph, next, isVisit))
                return true;
        }
        isVisit[start] = false;
        return false;
    }
};


题目:There is an m by n grid with a ball. Given the start coordinate (i,j) of the ball, you can move the ball to adjacent cell or cross the grid boundary in four directions (up, down, left, right). However, you can at most move N times. Find out the number of paths to move the ball out of grid boundary. The answer may be very large, return it after mod 109 + 7.

有一个mxn的格子,里面有一个球,起始坐标为(i,j)。球可以上下左右四个方向移动,移出格子外就不可以再移动。现在规定最多可以移动N次,问有多少种移动方法把球移出格子外。


思路:当前步数的情况和上一步的情况紧密相连,如果下一步能移出格子外,那总的情况数就加上当前坐标的情况数,如果不能移出格子外,当前坐标的情况数就加上上一步坐标的情况数。这里用动态规划做最合适。用一个三维数组dp[step][i][j]表示步数为step,坐标为(I,j)的时候能从起点移动到这个坐标的方法数目。转移方程就按照上面的思路实现。

class Solution {
public:
    int findPaths(int m, int n, int N, int i, int j) {
        int MOD = 1000000007;
        int dp[51][51][51] = {0};
        dp[0][i][j] = 1;
        int dirs[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
        int result = 0;
        for(int step = 1; step <= N; ++step)
        {
            for(int x = 0; x < m; ++x)
            {
                for(int y = 0; y < n; ++y)
                {
                    for(int i = 0; i < 4; ++i)
                    {
                        int new_x = x + dirs[i][0];
                        int new_y = y + dirs[i][1];
                        if(new_x < 0 || new_x >= m || new_y < 0 || new_y >= n)
                            result = (result + dp[step-1][x][y]) % MOD;
                        else
                            dp[step][new_x][new_y] = (dp[step][new_x][new_y]+dp[step-1][x][y]) % MOD;
                    }
                }
            }

        }
        return result;
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值