這裡有n
個房子在一列直線上,現在我們需要給房屋染色,共有k
種顏色。每個房屋染不同的顏色費用也不同,你需要設計一種染色方案使得相鄰的房屋顏色不同,並且費用最小。
費用通過乙個n
xk
的矩陣給出,比如cost[0][0]
表示房屋0
染顏色0
的費用,cost[1][2]
表示房屋1
染顏色2
的費用。
經典的動態規劃問題,假設當前的二維陣列是 :
[1,2,3]
[4,5,6]
[7,8,9]
有三座房子的情況:先生成動態規劃陣列 與原陣列大小相同dp;
dp[i][j]的含義代表在第i個房子選了j顏色時候 所需要最小的花費
如果只有一所房子的時候,房子的花費就只有三種情況
[1,2,3] 將這三種情況賦給dp[0] 也就是動態規劃陣列的第一行
第二行的時候要選擇就去選取與當前顏色不同,但花費最小的顏色
因為當前只有三種顏色所以 就要去選擇剩下兩種顏色花費最小的那乙個
dp[i][j]=
costs[i][j]+min(dp[i-1][1......n]);//n!=j;
動態規劃第二行就是[6,6,7]
同理就可以得到整個dp陣列,dp最後一行中最小的數就是花費最少的
但是 如果顏色的數量較多,時間複雜度就會提高到o(n*k*k) 就會超時;
我們可以在第一次遍歷dp[i-1]陣列的時候把 dp[i-1]這段陣列中的最小值
和次小值以及他們的下標儲存下來;當我們選取最小花費的時候 先看顏色
是不是和最小花費的房屋重複了,如果重複,我們就去累加次小值;
如果不重複就累加最小值。
這樣可以保證 時間複雜度降到o(n*k)
原始碼如下:
int mincostii(vector>& costs)
else if( dp[i-1][j] > minvalue&&dp[i-1][j] < nextminvalue)
}for( int n=0;n < lencolumn;n++)
}int min = dp[lenrow-1][0];
for( int i=1;idp[lenrow-1][i] )
min = dp[lenrow-1][i];
}return min;
}
我一直覺得lintcode這個oj很奇怪。。。。本來上面這段**是ac的但是又卡到了94%。。。
對上面的**進行分析發現在更新dp的過程中,先通過了乙個for迴圈來獲取上一層的最小值和
次小值。。。那麼實際的時間複雜度就變成了o(n*k*2)題目要求時間複雜度是o(n*k)所以有些問題
我們可以通過在累加dp陣列的過程中進行獲取最小值和次小值。在這一過程當中首先要對第一行的資料進行
初始化 包括最小值和次小值。。。通過只有兩個元素的小陣列來滾動更新。
int mincostii(vector>& costs)
else
雖然到這裡已經可以ac了 但是我發現還是有可以優化的餘地,將空間複雜度優化成o(n);
我們的可以直接把dp陣列的第一維去掉
int mincostii(vector>& costs)
else
else if(dp[j] >= minvalue[n]&&dp[j] < nextminvalue[n])}}
}n = 1-n;
}int min = int_max;
for(int i=0;idp[i])
min = dp[i];
return min;
}
房屋染色 LintCode
這裡有n個房子在一列直線上,現在我們需要給房屋染色,分別有紅色藍色和綠色。每個房屋染不同的顏色費用也不同,你需要設計一種染色方案使得相鄰的房屋顏色不同,並且費用最小。費用通過乙個nx3 的矩陣給出,比如cost 0 0 表示房屋0染紅色的費用,cost 1 2 表示房屋1染綠色的費用。注意事項 所有...
LintCode 516 房屋染色II
序列型動態規劃 與lintcode 515類似,由於顏色數從3變為k,源 經過簡單修改也可ac。time 3142mspublic class solution int res integer.max value for int i 0 i return res 但可在尋找最小值時進行優化,將原演算...
LintCode 534 打劫房屋 II
在上次打劫完一條街道之後,竊賊又發現了乙個新的可以打劫的地方,但這次所有的房子圍成了乙個圈,這就意味著第一間房子和最後一間房子是挨著的。每個房子都存放著特定金額的錢。你面臨的唯一約束條件是 相鄰的房子裝著相互聯絡的防盜系統,且 當相鄰的兩個房子同一天被打劫時,該系統會自動報警。給定乙個非負整數列表,...