我想知道可以将powerset问题转化并减少到背包问题吗?在我看来,它们是相同的,例如我们可以将其视为powerset的变化,每个递归阶段我发起2个递归调用(一个采用i
元素,另一个绕过它)。我也可以用动态编程解决它,就像背包问题一样,这让我想知道是否所有的powerset问题都可以转化为背包问题。那是对的吗 ?
以下是硬币变化的代码片段,其中一个具有O(2 N )时间复杂度,另一个具有动态编程O(N 2 )运行时。
// O(2^N) time complexity
void bruteforce(int[] coins, int i, int N, String expr)
{
if (i == coins.length) {
if (N == 0)
count++;
return;
}
if (N >= coins[i])
recursion(coins, i, N - coins[i], expr + " " + coins[i]);
recursion(coins, i + 1, N, expr);
}
// O(N^2) time complexity
int dynamicProgramming(int[] coins, int N)
{
int [] dp = new int[N + 1];
dp[0] = 1;
for(int i = 0; i < coins.length; i++)
for(int j = coins[i]; j <= N; j++)
dp[j] += dp[j - coins[i]];
return dp[N];
}
答案 0 :(得分:3)
查找powerset(生成集合的所有子集)不能以比O(2 n )更好的复杂度的方式完成,因为有2 n < / sup>子集并且仅打印它们将需要指数时间 诸如子集和,背包或硬币变化之类的问题与powerset有关,因为你 implicity 必须生成所有子集,但它们和powerset之间存在很大差异。在这些问题中,您只计算一些子集,并且您不需要明确生成这些子集。例如,如果问题要求您找到将X美元更改为某些硬币的所有方法,那么您无法在线性时间内解决此问题,因为您必须生成所有所需的子集,并且可能有2 n < / sup>他们。