优化DP解决方案的空间复杂性
Optimizing Space complexity for a DP solution
问题:
我有一张照片(黑白),以10个像素(1-D阵列)的形式给出在字符"b"answers"w"中,b表示黑色,w表示白色)
I也具有N个滤波器。每个滤波器都是一个1-D阵列(大小为10),包括"+"answers"-"。您可以选择这N个过滤器的任意子集并应用他们在照片上
应用筛选器:如果ith滤波器的特征是"+"反转中的ith像素照片其他什么都没发生
我们需要输出不同的过滤器子集我们可以选择将照片转换为全黑
限制:
1<T(测试用例的数量)<5
1<N(数量过滤器)<105
我的方法:
基本思想是我有一个函数NumberPossible(I,startingPosition),其中i是尚未使用的过滤器的索引。
i从0到n不等。
基本情况:NumberPossible(n,startingPosition)等于1当且仅当startingPosition为all黑色。否则为0
重复:数字可能(i,startingPosition)=数字可能(i+1,startingPosition))+数字可能的(i+1,startingPosition表示如何应用筛选器或不应用过滤器
问题:
以下方法超时(可能是由于步骤过于昂贵代码中提到的)。有更好的算法吗不需要存储所有状态,并且需要更少的空间复杂性
DP的概念是,从最终需要的信息,到一路上需要的所有中间信息,再到可以直接计算的信息,递归地向后工作。同时,您可以避免通过递归重新计算多个路径中所需的任何中间值。
但DP的典型现实是,知道哪些中间值已经计算出来的成本使得实际朝相反方向工作更便宜。从可以直接计算的内容开始。计算所有这些东西,不管你是否知道你会需要它们。然后走到可以从中计算的东西,并计算所有这些,再次不知道你是否需要它们。在典型的情况下,与以有效的顺序计算事物的好处相比,"无论你最终是否需要"的多余计算是微不足道的。
有一个语义问题(我看到这两个问题都得到了积极的维护),第二种方法是否真的是DP,或者DP是否只是第一种方法,假设的DP解决方案是否用于帮助定义非DP解决方案。
问题中的方向在本讨论中是一个令人困惑的因素,因为任何一种方法都允许可逆方向,但这两种方法之间的关键区别是方向相反。实际发生的情况与存储的答案的含义相反。
因此,让我们假设我们已经将j
计算为零或1,并且对于所有Y,dp[j][Y]
来表示考虑到对于某些i
的在i
之前的所有输入以及i
和j
之间的某些关系的组合(所有这些都发生在i
上的循环内)。
接下来,我们可以在Y上循环,以计算表示组合的所有Y的dp[1-j][Y]
,其中考虑了输入i
之前的所有输入。
之后,我们用1-j
交换j
(通过简单地编码j=1-j;
),或者从i
的下一个值重新计算j
。
我们可能想要检测并跳过输入中的一些空位置,这就是为什么将j
与1-j
交换为独立于递增i
的操作可能更好的原因。但这是一个相当高级的优化。
由于您知道如何从dp[i][]
、y
和输入i
计算dp[i+1][y]
,因此您知道如何将所有这些放入i
上的循环和y
上的内循环中,但请使用dp[j][]
和dp[1-j][]
。
接下来,更大的优化是计算输入。由于输入序列是不相关的,我们可以完全跳过filters
并使用filter_count[x]++
,而不是存储filters[i]=x
然后主CCD_ 29循环在CCD_ 30的1024个元素上,而不是在filter
的N个元素上。
sometype global_multiplier=1;
for (unsigned i=0; i<1024; ++i)
if (filter_count[i]) { // only do the work if we have any
// Multiply by half the number of subsets of this filter
for (unsigned c=filter_count[i]; --c;)
global_multiplier=(global_multiplier*2)%MOD;
for (unsigned y=0; y<1024; ++y)
dp[1-j][y] = (dp[j][y] + dp[j][y^i]) % MOD;
j=1-j;
}
最后,选择dp[j][]
的正确位置,并将其乘以单独保存的global_multiplier
您需要临时中的位数是MOD中位数的两倍。但在其他任何地方,您只需要在值中比MOD中多出一位。如果真的是强制的,最后一次乘法可以通过移位和加法来完成,所以它也只需要比MOD本身多一位。
- 运行同一解决方案的另一个项目的项目
- Project Euler问题4的错误解决方案
- 计算每个节点的树高,帮助我解释这个代码解决方案
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- visual c++,如何获取解决方案目录中的代码
- 有没有办法在远程设备上打开和编辑visual Studio 2017解决方案
- C++Matching Brackets 2解决方案不起作用
- 在 ubuntu3 上C++ goto 定义有什么解决方案吗16.04?
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的固定时间步长与增量时间和插值的解决方案是错误的吗?
- 无法在问题解决方案中执行输出逻辑
- 最大的回文产品 - 程序未运行,编写解决方案但无法理解问题
- 从预序遍历构造 bst 的 c++ 和 python 解决方案之间的区别
- 是否有可能实现O(N)时间和O(1)空间解决方案,以实现C++中的字符串循环移位
- 是否有一个很好的方法可以在C 11中打印出像JSON一样的Trie结构(仅迭代解决方案)的扁平命名空间
- 如何计算该程序的复杂性?是否有任何其他复杂性较低的解决方案
- 命名空间在C 中碰撞,坚持寻找解决方案
- 解决方案与命名空间/ADL 事物的标准一致性
- 优化DP解决方案的空间复杂性
- 多线程搜索的解决方案空间很大