三條面經題目

第一題:有m個餐廳,其中抽n個改造成停車場,使每個餐廳到最近的停車場距離之和最小

定義:dp[i][j]表示前i個餐廳有j個停車場的

初始:cost[k][i]表示第k個餐廳到第i個餐廳只有1個停車場服務時的最小矩離和
dp[i][1]的就是cost[1][i],注意只有1個停車場時一定是取中位數的位置

遞堆:dp[i][j]=min(dp[i][j],dp[k-1][j-1]+cost[k][i])
前i個餐廳有j個停車場相當於前k-1個餐廳有j-1個停車場,然後第k到i個餐廳有1個停車場

優化:四邊形不等式優化,對K的遍歷可以加速,由o(mmn)降爲o(mn)

 

第二題:找出數組中的最長子區間,和爲給定值k

例:[3,-2,-4,0,6,1],k=0
解:開map<int,int>,Key是前綴和,val是下標,先壓入<0,-1>,表示下標-1沒有數時和就是0
到下標0位置,由於當前sum是3,要找區間和是0,則要找map有沒有前綴和是3-0=3,但是沒有故跳過,壓入<3,0>
到下標1位置,由於當前sum是1,要找區間和是0,則要找map有沒有前綴和是1-0=1,但是沒有故跳過,壓入<1,1>
到下標2位置,由於當前sum是-3,要找區間和是0,則要找map有沒有前綴和是-3-0=-3,但是沒有故跳過,壓入<-3,2>
到下標3位置,由於當前sum是-3,要找區間和是0,則要找map有沒有前綴和是-3-0=-3,有<-3,2>,得到區間[3,3],不用壓入
到下標4位置,由於當前sum是3,要找區間和是0,則要找map有沒有前綴和是3-0=3,有<3,0>,得到區間[1,4],不用壓入
以下標5位置,由於當前sum是4,要找區間和是0,則要找map有沒有前綴和是4-0=4,但是沒有故跳過,壓入<4,5>
結束,獲得最長子區間[1,4]

補充解釋爲何下標3(下標4同理)不用壓入<3,3>:因爲前面有<3,0>,取下標較小的就能獲得較長的區間

 

第三題:找到數組中的最長子區間,和小於等於給定值k

例:[3,-2,-4,0,6],k=-2
解:開map<int,int>,Key是前綴和,val是下標,先壓入<0,-1>,表示下標-1沒有數時和就是0
到下標0位置,由於當前sum是3,要找區間和小於等於-2,則要找map有沒有前綴和是大於等於3-(-2)=5,但是沒有故跳過,壓入<3,0>
到下標1位置,由於當前sum是1,要找區間和小於等於-2,則要找map有沒有前綴和是大於等於1-(-2)=3,有<3,0>,找到區間[1,1],不用壓入<1,1>【優化,見解釋】
到下標2位置,由於當前sum是-3,要找區間和小於等於-2,則要找map有沒有前綴和是大於等於-3-(-2)=-1,有<3,0>與<0,-1>,找到區間[0,2],不用壓入<-3,2>
到下標3位置,由於當前sum是-3,要找區間和小於等於-2,則要找map有沒有前綴和是大於等於-3-(-2)=-1,有<3,0>與<0,-1>,找到區間[0,3],不用壓入<-3,3>
到下標4位置,由於當前sum是3,要找區間和小於等於-2,則要找map有沒有前綴和是大於等於3-(-2)=5,但是沒有故跳過,不用壓入,因爲<3,0>比<3,4>有更小下標
結束,獲得最長子區間[0,3]

補充解釋爲何不用壓入<1,1>:因爲對比<3,0>,設現在要找map中找的前綴和值是x,若1大於等於x,則3必然大於等於x,而<3,0>有更優的下標0,所以不用壓入<1,1>
同理,<-3,2>也不如<3,0>優,因此可以得到結論,壓入map的前綴和值一定是單調遞增的,因爲下標肯定不斷增,前綴和若是有比以前小的,在選擇時一定不是最優

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章