I love sneakers! HDU - 3033

分組揹包的問題,一開始沒想到,看到有個大佬寫的挺好的,他是這樣寫的:

分組揹包問題,大意**要買鞋,有k種牌子,每種牌子至少買一雙鞋子。每雙鞋子有標價跟實際價值。求用m多的錢買最多價值的鞋。

其實我覺得這題的難點就在處理“至少”這點上面。

狀態方程很多都能推出用 dp[k][m] 來表示 已經買了k種鞋 在有m錢狀態下的 鞋的最大價值。

狀態轉移方程爲

    for( k = 1 ; k <= K ; k++)
    {
        for( i = 0 ; i < num[k] ; i++)
        {
            for( j = mm ; j >= m[k][i].m ; j--)
            {
                if(dp[k][j - m[k][i].m] != -1)
                    dp[k][j] = Max(dp[k][j] , dp[k][j - m[k][i].m] + m[k][i].v);
                if(dp[k-1][j - m[k][i].m] != -1 )
                    dp[k][j] = Max(dp[k][j] , dp[k-1][j - m[k][i].m] + m[k][i].v);

            }
        }
    }

如果忽略了兩個紅色的判斷句,大家都看得出這只是單純的01揹包且 沒有條件限制,加了這兩句就能實現至少了。理由如下

一開始我將dp[][]數組初始化爲-1表示所有的數都不合法。大於0表示合法
然後將所有的 k = 0 dp[0][]置爲0,這是爲了 k = 1時能合法計算。

從狀態方程中看出,當上一個狀態值爲-1時表示他不合法。所以當前狀態沒有計算的必要也不合法答案。

如果計算完第k類商品的取值後,所有的dp[k][]均爲-1的時候,第k類表明沒有一鞋被買。故所有狀態都不合法,接下來的所有值也都將不合法。

在計算第k組商品的過程中,當某個-1變成一個非負數的時候,也就表明當前的第k種已經拿了第i件物品,所以變成合法答案了。

如此推下去,最後一個值dp[k][m],就是答案了。如果依然是-1,就輸出impossible把。

5 13 3
1 2 3
1 4 6
2 10 2
3 2 2
3 1 2
7

m k=0 k=1 k=2 k=3
0 0 -1 -1 -1
1 0 -1 -1 -1
2 0 3 -1 -1
3 0 3 -1 -1
4 0 6 -1 -1
5 0 6 -1 -1
6 0 9 -1 -1
7 0 9 -1 -1
8 0 9 -1 -1
9 0 9 -1 -1
10 0 9 -1 -1
11 0 9 -1 -1
12 0 9 5 -1
13 0 9 5 7
地址

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