求n*m網格內矩形的數目


一個n*m的網格,求這個網格中矩形的數目。

比如以下2*2網格,總共有9個矩形:4個1*1的矩形,4個1*2的矩形,1個2*2的矩形

image

 

算法1:動態規划,假設dp[i][j]表示以第 i 行第 j 列的格子為右下角頂點的矩形數目,那么dp[i][j] = 1 + dp[i-1][j] + dp[i][j-1] – dp[i-1][j-1] , 這里的1表示i ,j 位置的格子自身構成1*1的矩形,之所以減去dp[i-1][j-1], 因為dp[i-1][j] 和 dp[i][j-1] 都包含了dp[i-1][j-1]。計算時注意i = 1 和 j = 1的邊界條件。最后把所有dp[i][j]加起來就是我們所求的答案。以3*3網格舉例,為了計算方便,紅色為設置的邊界值,黑色的才是最后需要加起來的值(結果為36)

image

 

 

int rectNum(int row, int column)
{
    vector<vector<int> >dp(row+1, vector<int>(column+1, 1));
    int res = 0;
    dp[0][0] = 2;
    for(int i = 1; i <= row; i++)
        for(int j = 1; j <= column; j++)
        {
            dp[i][j] = 1 + dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1];
            res += dp[i][j];
        }
    return res;
}

 

算法2:我們假設網格是1行m列的,那么總的矩形數目 = m(1*1的矩形) + m-1(1*2的矩形) + m-2(1*3的矩形) +…+1(1*m的矩形) = m*(m+1)/2,同理n行1列總的矩形數目是n*(n+1)/2. 對於n*m的網格,我們可以先確定好選取的行數(即確定矩形的高),公共有n*(n+1)/2種選法,選好以后就可以壓縮成1行m列的網格來考慮了,因此總共n*(n+1)/2*m*(m+1)/2個矩形。(注意最后結果是否溢出int范圍)                 本文地址

int rectNum(int row, int column)
{
    return row*(row+1)*column*(column+1)/4;
}

 

算法2還可以這樣理解:兩個對角點就可以確定一個矩形。對於一個n*m的網格,總共有(n+1)*(m+1)個頂點,因此第一個頂點有(n+1)*(m+1)種選取方法,選取好第一個頂點后,第二個頂點就有一些限制了,它不能和第一個頂點在同一條直線上,因此第二個頂點有n*m種選取方法;因此選取兩個頂點總共有(n+1)*(m+1)*n*m種選取方法,考慮到矩形ABCD,選取AC、CA、BD、DB都表示同一個矩形,即這些選取方法中,包含的每個矩形都重復了四次,因此總共有(n+1)*(m+1)*n*m/4個矩形。

 

可以在hduoj 2524上測試算法的正確性

 

【版權聲明】轉載請注明出處:http://www.cnblogs.com/TenosDoIt/p/3740141.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM