Leetcode dp問(wèn)題匯總

面試題47. 禮物的最大價(jià)值

概述:在一個(gè) m*n 的棋盤的每一格都放有一個(gè)禮物,每個(gè)禮物都有一定的價(jià)值(價(jià)值大于 0)。從棋盤的左上角開始拿格子里的禮物,并每次向右或者向下移動(dòng)一格、直到到達(dá)棋盤的右下角。給定棋盤及其上面的禮物的價(jià)值,求最大價(jià)值。
思路:剛開始爆搜去了,果斷給我T了,把數(shù)據(jù)緩存下來(lái)就a了,

int row,col;
    int map1[201][201];
    int maxValue(vector<vector<int>>& grid) {
     row=grid.size();
     if(!row) return 0;
     col=grid[0].size();
      return dfs(0,0,grid);
    }
    int dfs(int x,int y,vector<vector<int>>& grid){
        if(x>=row||y>=col) return 0;
        if(map1[x][y]>0) return map1[x][y];
        int a=dfs(x+1,y,grid),b=dfs(x,y+1,grid);
         map1[x][y]=grid[x][y]+max(a,b);
         return map1[x][y];
    }

打開題解一看,都是dp,,,
這是二維dp,用一個(gè)二維數(shù)組保存狀態(tài),dp方程dp[i][j]=max(dp[i-1][j],dp[i][j-1])+grid[i][j]
初始條件是0行0列的值,因?yàn)樗峭彝屡艿摹?/p>

    int row,col;
    int map1[201][201];
    int maxValue(vector<vector<int>>& grid) {
     row=grid.size();  if(!row) return 0;
     col=grid[0].size();
     int dp[201][201];
     dp[0][0]=grid[0][0];
     for(int i=1;i<col;i++) dp[0][i]=dp[0][i-1]+grid[0][i];
     for(int i=1;i<row;i++)  dp[i][0]=dp[i-1][0]+grid[i][0];
     for(int i=1;i<row;i++)
         for(int j=1;j<col;j++)
             dp[i][j]=max(dp[i-1][j],dp[i][j-1])+grid[i][j];
     return dp[row-1][col-1];
    }

可以優(yōu)化成一維的

    int dp[201];
    int maxValue(vector<vector<int>>& grid) {
       int row=grid.size();
       int col=grid[0].size();
       for(int i=0;i<row;i++)
           for(int j=0;j<col;j++)
               dp[j+1]=max(dp[j],dp[j+1])+grid[i][j];
      return dp[col];
    }

264. 丑數(shù) II

概述:按順序找出前1670個(gè)丑數(shù),丑數(shù)就是只包含質(zhì)因數(shù) 2, 3, 5 的正整數(shù)。
思路:這道題因?yàn)橄乱粋€(gè)丑數(shù)可由之前丑數(shù)計(jì)算出來(lái),當(dāng)前狀態(tài)由之前狀態(tài)得出,滿足無(wú)后效性,也算是dp。
采用三指針做法,計(jì)算丑數(shù)時(shí)是選取三個(gè)里最小的那一個(gè),然后將這個(gè)指針后移一位。

   int nthUglyNumber(int n) {
       double res[1693];
        int p2=0,p3=0,p5=0;
        res[0]=1;
     for(int i=1;i<1691;i++){
          res[i]=min(2*res[p2],min(3*res[p3],5*res[p5]));
          if(res[i]==2*res[p2]) p2++;
          if(res[i]==3*res[p3]) p3++;
          if(res[i]==5*res[p5]) p5++;
     }
     return (int)res[n-1];
    }

338. 比特位計(jì)數(shù)

概述:0-num中每一個(gè)數(shù)字的二進(jìn)制表示1的個(gè)數(shù),O(n)的復(fù)雜度
思路:動(dòng)態(tài)規(guī)劃的思想,當(dāng)num為奇數(shù)時(shí)候,num-1是偶數(shù),1的個(gè)數(shù)就是num-1中1的個(gè)數(shù)加1,
當(dāng)num為偶數(shù)時(shí)候,num-1為奇數(shù),num不過(guò)是 num/2左移一位(可以理解為末尾加了個(gè)0),而1的個(gè)數(shù)沒(méi)有發(fā)生改變。

    vector<int> countBits(int num) {
        vector<int>res;
        /*for(int i=0;i<=num;i++){ //我的暴力代碼  果斷tttt
            int cnt=0;
            while(i){
                if(i&1==1) cnt++;
                i>>1;
            }
            res.push_back(cnt);
        }
        */
        res.push_back(0);
         for(int i=1;i<=num;i++){
             int cnt=0;;
             if(i&1) cnt=res[i-1]+1;
              else cnt=res[i/2];
              res.push_back(cnt);
         }
/*
      int[] ans = new int[num + 1]; //官方題解里的最低有效位的方法,比我的寫起來(lái)更簡(jiǎn)潔一些,
      for (int i = 1; i <= num; ++i)
        ans[i] = ans[i >> 1] + (i & 1);
*/
        return res; 
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容