Idea : esta pregunta es muy similar desde la perspectiva de la programación dinámica0-1 problema de mochila, Este último necesita maximizar el valor bajo la condición de menor o igual a la capacidad de la mochila, aquí es exactamente igual a la mitad de la suma de la matriz;
1 °, para cumplir con la condición, la suma de la matriz sum
debe ser un número par, y el valor objetivo target=sum/2
, todo lo que tiene que hacer es Encuentre varios elementos en la matriz y haga que la suma sea target
;
2 °, establezca un modelo de programación dinámica bool dp[len][taeget+1]中,dp[i][j]的值表示数组[0,i]中是否存在若干个元素的和为j
,;
3 °, condición de frontera {对于所有dp[i][0]=true,因为数组[0,i]我都可以不选从而达到j=0的条件} {dp[0][nums[0]]=true,选择数组第一个元素(nums[0])能让j=nums[0]满足}
4 °, dp[i][j]
hay dos casos para el valor de:
- Si
j<nums[i]
, entonces nonums[i]
debe seleccionarse, es más de j =>dp[i][j]=dp[i-1][j]
- Si
j>=nums[i]
, entoncesnums[i]
puede elegir no elegir =>df[i][j]=dp[i-1][j](不选)||dp[i-1][j-nums[i]](选)
5 °, finalmentereturn dp[len-1][target]
puede
La versión detallada se puede encontrar en la solución => Solución oficial de Leikou
class Solution {
public:
bool canPartition(vector<int> &nums)
{
int len = nums.size();
if (len < 2)
return false;
if (len == 2 && nums[0] != nums[1])
return false;
int sum = 0, target = 0;
for (int i = 0; i < len; i++)
{
sum += nums[i];
}
if (sum & 1) //如果sum是奇数,直接return false
{
return false;
}
else //如果是偶数,说明可能为true 可能为false,如果能凑出若干整数使它们和为sum/2,说明为true
{
target = sum / 2;
}
//dp[i][j]标识从数组[0,i]下标范围内选区若干整数(可以是0个),是否存在一种方案使得被选取得正整数和等于j
bool **dp = new bool *[len];
for (int i = 0; i < len; i++)
{
dp[i] = new bool[target + 1];
for (int j = 0; j < target + 1; j++)
{
dp[i][j] = false;
}
}
//边界条件1:对于所有j=0,dp[i][0]=true,因为我可以选0个达到j=0;
for (int i = 0; i < len; i++)
{
dp[i][0] = true;
}
//边界条件2:当i=0时,只有1个整数(nums[0])能被选到,所以dp[0][nums[0]]=true
dp[0][nums[0]] = true;
for (int i = 1; i < len; i++)
{
for (int j = 1; j < target + 1; j++)
{
//如果j>=nums[i],则nums[i]可选可不选
if (j >= nums[i])
{
// 选nums[i] 不选nums[i]
dp[i][j] = dp[i - 1][j - nums[i]] || dp[i - 1][j];
}
//如果j<nums[i],则说明nums[i]必不能选
else
{
dp[i][j] = dp[i - 1][j];
}
}
}
return dp[len - 1][target];
}
};