1. 程式人生 > 其它 >陣列劃分成兩個和相等的子集(動態規劃)

陣列劃分成兩個和相等的子集(動態規劃)

給一隻含有正整數的非空陣列, 判斷這個陣列是否可以劃分為 兩個元素和相等的子集。

注意事項:
所有陣列元素不超過100.
陣列大小不超過200.

樣例:
給一陣列 [1, 5, 11, 5] , 返回 true ,
兩個子集:[1, 5, 5], [11]
給一陣列 [1, 2, 3, 9] , 返回 false

思路:
動態規劃,對於陣列nums,判斷奇偶性,若為奇數,肯定不可能分成兩個相等的數,
若為偶數,令sum為陣列nums元素和的一半。構建陣列dp[len][sum],dp[i][j]表示nums的第一個元素到
第i個元素構成的集合中,是否存在使得和為j的子集。

for (int i = 0; i <= len; ++i)
dp[i][0] = true; //和為0是不可能存在的,因為這是一個正整數vector
for (int i = 1; i <= len; ++i) //遍歷陣列
{
for (int j = 1; j <= sum; ++j)
{
if (j >= nums[i - 1]) //如果j大於等於第i個元素
dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i - 1]]; 那麼我們就將dp【i】【j】設定為要麼滿足上一層中和為j的元素,要麼//

//就滿足和等於j減去元素的第i位。揹包問題即,將問題變為一個個的小問題,高層由低層決定。

也就是把A問題 “前i位的和能不能等於j” 轉化為——B問題 “前i-1位的和能不能等於j” 和C 問題 “前i-1位的和能不能等於j- nums【i-1】”,然後以此類推。
else
dp[i][j] = dp[i - 1][j];
}
}
return dp[len][sum];
}
};
#endif