dp基礎之位移問題
問題:求從0到N(包括N)的二進位制表示裡有多少個1?
動態規劃解決,分析:要求N的二進位制裡有多少個1,可以先求N去掉最後一位(N mod 2)後Y(Y = X>>1)裡有多少個1
子問題:f[i]表示數字i的二進位制裡有多少個1
f[i] = i>>1 + i mod 2
數字i的二進位制裡有多少個1 = i去掉最後一位裡的二進位制有多少個1 + i的最後一位(有可能是1或0)
初始狀態f[0] = 0,
計算順序:從f[0]...f[N]
時間複雜度達到O(n)
程式碼及註釋如下:
def Number_Of_One(N): #f[i]表示數字i的二進位制裡有多少個1 f = [0 for i in range(N+1)] for i in range(1,N+1): f[i] = f[i>>1] + i%2 return f N = 5 print(Number_Of_One(N)) 結果是:[0, 1, 1, 2, 1, 2]
相關推薦
dp基礎之位移問題
問題:求從0到N(包括N)的二進位制表示裡有多少個1? 動態規劃解決,分析:要求N的二進位制裡有多少個1,可以先求N去掉最後一位(N mod 2)後Y(Y = X>>1)裡有多少個1 子問題:f[i]表示數字i的二進位制裡有多少個1 f[i] = i>>1 + i mod
dp基礎之網格問題
問題1:在一個m*n的網格里,從左上到右下一共有多少種路徑,要求,只能向右或向下走?(m,n>0) 程式碼及註釋如下: #!/usr/bin/python def get_case(m,n): #m,n分別為網格的行列數 #建立一個列表 #f[i][j]表示從左上開始到第i行第j
dp基礎之計數型硬幣問題
解決DP問題的四大步驟: 1.確定狀態:研究最有策略的最後一步,轉化為子問題 ,重點 2.轉移方程:根據子問題定義直接得到轉移方程,男點 3.初始條件和邊界情況:注意點 4.計算順序:最好能利用之前計算好的結果,省得重複計算,技巧點 問題:現有2,5,7三種硬幣足夠數量,要拼湊成
dp基礎之序列型油漆房子
問題:有一排N棟房子,每棟房子要油漆成紅、藍、綠三種顏色,第i棟房子油漆成紅、藍、綠的花費分別為cost[i][0]、cost[i][1]、cost[i][2] 要求:相鄰的房子顏色需不同 求油漆好房子的最小花費 程式碼及註釋如下: def Pint_huose(cost)
dp基礎之存在性dp問題
問題:在x軸上,從0到n-1,對應一個一維陣列A,要求,每次在位置i只向右跳最多A[i]的長度,問最終能不能到達位置n-1? 程式碼及註釋如下: #!/usr/bin/python def get_case(A): n = len(A) #建立一個列表 #f[i]表示能不能跳到位置i,
dp基礎之劃分型數字解密
#問題:有一段A-Z組成字母資訊串被加密數字串,加密方式A-1,B-2...給定加密後的數字串有多少種解密方式? 程式碼及註釋如下: def get_case(s): #f[i]表示前i個數字可以解密成的種數 n = len(s) if n==0:
dp基礎之劃分型劃分最少完全平方數個數
問題:給定一個正整數n,問:最少可以將n分成幾個完全平方數(1 4 9 16..)之和? 例: 輸入:n = 13 13 = 4+9 輸出:2 分析: 狀態確定:最優策略中最後一步,假設n的最優劃分的最後一個平方數是j, 則需要知道n-j^2的最優劃分 轉移方程: 設:f[i]表示i的最
dp基礎之序列型最長上升子序列
問題 :給定a[i](i=0...n-1),找到最長上升子序列(假設長度為k),輸出k 例: a = [4,2,4,5,3,7] 返回 k=4([2,4,5,7]) 分析: 對於最優策略:一定有最後一個元素a[j] 情況1:最優策略就是{a[j]},長度k就是1 情
dp基礎之序列型Stock
問題:已知後N天 的股票價格為p[0]...p[N-1](N>=2) 要求:可以最多買一股賣一股, 求最大獲利 分析: 列舉第j天賣(0<j<=N-1) 儲存j天之前第i天賣的最小值(i<j) &nbs
dp基礎之序列型House Robber
問題:有一排房子N棟,房子i 裡有金幣 house[i],現有小偷想選擇而一些房子偷金幣,為了防止被抓,不能偷相鄰兩棟房子,問最多能偷多少錢? 分析; 在最優策略中,偷或不偷房子N-1 1不偷,則最優策略就是前N-1棟房子的最優策略 2偷,
dp基礎之劃分型劃分最小劃分次數
問題:給定一個字串S[0,..n-1],最少劃分幾次使得每個子串都是迴文串 確定狀態:最優策略中最後一段迴文串是S[j...n-1] 需要知道S前j個字元[0...j-1]最少可以劃分成幾個迴文串 子問題: 設:S前i個字元[0...i-1]最少可以劃分成f[i]個迴
dp基礎之劃分型抄寫書的最短時間
問題:有N本書需要抄寫,每本書的頁數分別為A[0]...A[N-1],現有K個抄寫員。每個抄寫員可以連續抄寫若干本書,每個抄寫員的抄寫速度一樣一分鐘一頁,問最少需要多長時間抄寫完所有的樹。 例: A = [3,2,4],K = 2 最少時間為:5 分析:若一個抄寫員抄寫A[i.
dp基礎之揹包問題小結
可行性揹包問題:最多能裝多少重量,需要記錄前 i 個物品能不能拼出重量W(w=0...Target),如dp基礎之揹包問題裡的問題一,用f[i][w]表示前i個物品能不能拼出重量w,f[i][w] = True/False 計數型揹包問題:有多少種方式拼出重量,如dp基礎之揹包
dp基礎之揹包問題
問題一:有N個物品,重量為A[0]...A[N-1],有一個容量為M(M是一個正整數)。 問:最多能帶走多重的物品。 例:A = [2,3,5,7] M = 10 輸出:10(2,3,5) 問題分析: 要求N個物品能否拼出重量W(W = 0,1...M),需要知道前N
dp基礎之博弈型取石子
對於博弈型dp,一般是從複雜走向簡單,故不從最後一步開始分析,反而從第一部開始分析 問題:一排N個硬幣,兩人先後從最右邊取一個或兩個硬幣,規定取走最後石子的人為勝。 問先手是否必勝(先手必勝:True;先手必敗:False) 例: N = 5 輸出:True,先手必勝
dp基礎之雙序列型最長公共子串
問題:給定兩個字串A,B,找到兩個字元互傳的公共最長子串的長度。 子串:在原字串上去去掉某些字元後形成的字串,不改變字元之間的順序 例: A = ['j', 'i', 'u', 'z', 'h', 'a', 'n', 'g'] B = ['l', 'i', 'j', 'i', 'a', 'n', '
dp基礎之區間型炸氣球
問題:有N個氣球A[1],...A[N],扎破第i個氣球所得的金幣A[left]*A[i]*A[right],扎破氣球i後, 氣球left和right就變成相鄰的氣球,求獲得最多的金幣數,A[0] = A[N+1] = 1 例: A = [3,1,5,8] [3,5,8]-->[3,8]--&
dp基礎之博弈型和區間型結合輪流取數字
問題:給定一個序列A[0],..,A[N-1],兩個人輪流從序列兩頭取數字(每次只取一個),雙方都用最優策略,使自己的取到的數字和儘量比對手大。 問先手是否必勝?當和一樣大時規定先手勝。(True/False) 例: A = [1,5,233,7] 輸出:True(,先手取1,無論後手取哪個,先手都
dp基礎座標型問題之最長單調子序列
問題:最長連續上升子序列長度,或者說最長連續單調子序列 程式碼及註釋如下: def get_length(A): #f[i]表示以A[i]結尾的最長上升子序列的長度 n = len(A) #最終結果 res = 0 if n==0:
Re0:DP學習之路 數塔 HDU - 2084(基礎遞推)
解法 首先是輸入的問題,輸入的時候還要注意每一層都有多少個 然後是怎麼求解,一般求解首先要考慮順序,是正序還是倒序 如果這個題是正序的話那麼最終還需要將最後一行進行一次找max的運算 如果是倒序的話那麼最終歸於同一個起點,直接進行輸出即可 轉移方程 轉移方程考慮把問題分散化,分散成小的問題,其中這