力扣周賽 5431. 給房子塗色 III

在一個小城市裏,有 m 個房子排成一排,你需要給每個房子塗上 n 種顏色之一(顏色編號爲 1 到 n )。有的房子去年夏天已經塗過顏色了,所以這些房子不需要被重新塗色。

我們將連續相同顏色儘可能多的房子稱爲一個街區。(比方說 houses = [1,2,2,3,3,2,1,1] ,它包含 5 個街區  [{1}, {2,2}, {3,3}, {2}, {1,1}] 。)

給你一個數組 houses ,一個 m * n 的矩陣 cost 和一個整數 target ,其中:

houses[i]:是第 i 個房子的顏色,0 表示這個房子還沒有被塗色。
cost[i][j]:是將第 i 個房子塗成顏色 j+1 的花費。
請你返回房子塗色方案的最小總花費,使得每個房子都被塗色後,恰好組成 target 個街區。如果沒有可用的塗色方案,請返回 -1 。

 

示例 1:

輸入:houses = [0,0,0,0,0], cost = [[1,10],[10,1],[10,1],[1,10],[5,1]], m = 5, n = 2, target = 3
輸出:9
解釋:房子塗色方案爲 [1,2,2,1,1]
此方案包含 target = 3 個街區,分別是 [{1}, {2,2}, {1,1}]。
塗色的總花費爲 (1 + 1 + 1 + 1 + 5) = 9。
示例 2:

輸入:houses = [0,2,1,2,0], cost = [[1,10],[10,1],[10,1],[1,10],[5,1]], m = 5, n = 2, target = 3
輸出:11
解釋:有的房子已經被塗色了,在此基礎上塗色方案爲 [2,2,1,2,2]
此方案包含 target = 3 個街區,分別是 [{2,2}, {1}, {2,2}]。
給第一個和最後一個房子塗色的花費爲 (10 + 1) = 11。
示例 3:

輸入:houses = [0,0,0,0,0], cost = [[1,10],[10,1],[1,10],[10,1],[1,10]], m = 5, n = 2, target = 5
輸出:5
示例 4:

輸入:houses = [3,1,2,3], cost = [[1,1,1],[1,1,1],[1,1,1],[1,1,1]], m = 4, n = 3, target = 3
輸出:-1
解釋:房子已經被塗色並組成了 4 個街區,分別是 [{3},{1},{2},{3}] ,無法形成 target = 3 個街區。
 

提示:

m == houses.length == cost.length
n == cost[i].length
1 <= m <= 100
1 <= n <= 20
1 <= target <= m
0 <= houses[i] <= n
1 <= cost[i][j] <= 10^4

 

我比賽提交的的代碼:

int maxint=1234567;
class Solution {
public:
    int ans[105][22][105];
    int dp(vector<int>& houses, vector<vector<int>>& cost, int m, int n,int nn, int target) {
        if(m==0)
        {
            if(target!=1)return maxint;
            if(houses[m]>0)return 0;
            return cost[0][nn-1];
        }
        if(target<=0)return maxint;
        if(ans[m][nn][target]<maxint)return ans[m][nn][target];
        if(houses[m]>0 && houses[m]!=nn)return maxint;
        for(int ni=1;ni<=n;ni++)ans[m][nn][target]=min(ans[m][nn][target],((houses[m]>0)?0:cost[m][nn-1])+dp(houses,cost,m-1,n,ni,target-(ni!=nn)));
        return ans[m][nn][target];
    }
    int minCost(vector<int>& houses, vector<vector<int>>& cost, int m, int n, int target) {
        for(int i=0;i<=m;i++)for(int j=0;j<=n;j++)for(int k=0;k<=target;k++)ans[i][j][k]=maxint;
        int r=maxint;
        for(int ni=1;ni<=n;ni++)r=min(r,dp(houses,cost,m-1,n,ni,target));
        if(r==maxint)return -1;
        return r;
    }
};

結果是解答錯誤,加上第九行

if(houses[m]>0 && houses[m]!=nn)return maxint;

解決了計算錯誤的問題,但是超時了。

仔細一分析,在於我的maxint這個值既用作初始值,也用作表示無解的-1,造成了混亂。

要區分這個,我加了一行,改了一行,代碼變成:

int maxint=1234567;
class Solution {
public:
    int ans[105][22][105];
    int dp(vector<int>& houses, vector<vector<int>>& cost, int m, int n,int nn, int target) {
        if(m==0)
        {
            if(target!=1)return maxint;
            if(houses[m]>0 && houses[m]!=nn)return maxint;  ////////add
            if(houses[m]>0)return 0;
            return cost[0][nn-1];
        }
        if(target<=0)return maxint;
        if(ans[m][nn][target]<maxint)return ans[m][nn][target];
        if(houses[m]>0 && houses[m]!=nn)return maxint;
        ans[m][nn][target]--;  ////////add
        for(int ni=1;ni<=n;ni++)ans[m][nn][target]=min(ans[m][nn][target],((houses[m]>0)?0:cost[m][nn-1])+dp(houses,cost,m-1,n,ni,target-(ni!=nn)));
        return ans[m][nn][target];
    }
    int minCost(vector<int>& houses, vector<vector<int>>& cost, int m, int n, int target) {
        for(int i=0;i<=m;i++)for(int j=0;j<=n;j++)for(int k=0;k<=target;k++)ans[i][j][k]=maxint;
        int r=maxint;
        for(int ni=1;ni<=n;ni++)r=min(r,dp(houses,cost,m-1,n,ni,target));
        if(r>maxint-2)return -1;   ////////modify
        return r;
    }
};

這個是AC的

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