常规01背包
poj 3624. Charm Bracelet(AC代码)
int backPack_01()
{
memset( dp, 0, sizeof(dp) );
for( int i = 0; i < n; i++ )
for( int c = C; c >= w[i]; c-- ) // 逆序遍历
dp[c] = max( dp[ c - w[i] ] + v[i], dp[c] );
return dp[C];
}
Subset Sum(物品的重量和价值相等)
问题1:求不大于target
的最大subset sum
int dp[target + 10]; // dp[c]表示不超过c的最大subset sum
memset( dp, 0, sizeof(dp) );
for( int i = 0; i < n; i++ )
for( int c = target; c >= nums[i]; c-- ) // 逆序遍历
dp[c] = max( dp[ c - nums[i] ] + nums[i], dp[c] );
问题2:求等于target
的subset sum是否存在
bool dp[target + 10]; // dp[c]表示和为c的subset sum是否存在
memset( dp, false, sizeof(dp) ); // 默认不存在
dp[0] = true; // 和为0的方案存在
for( int i = 0; i < n; i++ )
for( int c = target; c >= nums[i]; c-- ) // 逆序遍历
dp[c] = dp[c] || dp[c - nums[i]];
问题3:求等于target
的subset sum的方案数(方案数可能很大,建议用long long
)
long long dp[target + 10]; // dp[c]表示和为c的subset sum方案数
memset( dp, 0, sizeof(dp) );
dp[0] = 1; // 和为0的方案数为1
for( int i = 0; i < n; i++ )
for( int c = target; c >= nums[i]; c-- )
dp[c] = dp[ c - nums[i] ] + dp[c];