UniquePath

这里两道题目,虽然只有一点差别,但是前者可以用一个组合数直接算出,后面则需要DP。

先看第一道,似乎是之前编程之美看过的Catalan数那题的一道课后习题,也是问从二维空间坐上到右下之类的,
最多有多少unique条路径,一开始我以为是n-1 里面插入m-1个位置,然后加上n-1个数两端n个插入m-1个位置,
然后以为是C(n,m-1),如果大的话反过来,后来发现错了,这样会漏掉m-1个数连续放在一起的情况,因为未必每个都单独占一个坑,
所以还是统一起来看,n-1+m-1个位置里选n-1(m-1), 不考虑顺序的,因为选定之后,只有一种排列,因此是组合数。但是测了发现OJ有个错误,
其实当n=m=100, 到最大范围时已经超了int的范围,如果用double每次乘以一个比例的话最后精度会丢导致结果出错,但是似乎最大198连乘到100似乎超过了
最大的范围了,包括unsigned long long, long double 都超了,所以即使不要求返回int,似乎需要bitset来处理乘积嘛。

class Solution {
public:
    int uniquePaths(int m, int n) {
        //double product=1;
        unsigned long long up=1,down=1;
        if(n>m) swap(n,m);
        for(int i=n-1;i>=1;i--)
        {
            up*=(unsigned long long)(m-1+i);
            down*=(unsigned long long)(i);
        }
        unsigned long long a=up/down;
        return (int)a;
        //product*=(double(m-1+i)/(i));//:i=n-1->1
        //return (int)product;
    }
};

第二道放了障碍,简单的DP,但是甩了几脚,当上和左都不是障碍时,我把条件与了,其实如果分别一个是的话,也是可以算的,所以这里没有仔细考虑算法,还有就是DP都是1…m 1..n这个是经验,
然后数据都从0开始,因此DP基本都要和数据下表相差1,数据要-1 包括ij

class Solution {
public:
    int dp[200][200];
    int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) {

        int m=obstacleGrid.size();
        if(m==0) return 0;
        int n=obstacleGrid[0].size();
        if(n==0) return 0;
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=n;j++)
            {
                dp[i][j]=0;
                if(obstacleGrid[i-1][j-1]==1) continue;
                if(i>=2 && j>=2)
                {
                    if(obstacleGrid[i-2][j-1]==0)
                        dp[i][j]+=dp[i-1][j];
                    if(obstacleGrid[i-1][j-2]==0)
                        dp[i][j]+=dp[i][j-1];
                }
                else if(i==1 && j>=2 && obstacleGrid[i-1][j-2]==0)
                    dp[i][j]=dp[i][j-1];
                else if(i>=2 && j==1 && obstacleGrid[i-2][j-1]==0)
                    dp[i][j]=dp[i-1][j];
                else if(i==1 && j==1)
                    dp[i][j]=1;
            }
        }
        /*
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=n;j++)
                cout<<dp[i][j]<<" ";
            cout<<endl;
        }*/
        return dp[m][n];

    }
};

不优化反而变成了WA了,一直以为有什么边界没处理,结果是空间没优化,最后200MB内存,01背包还是要空间优化

Posted by richard爱闹 - 8月 9 2014
如需转载,请注明: 本文来自 Richard