我试图找到并解决UVA #11450的动态编程方法的递归关系。作为免责声明,这是我大部分时间完成的家庭作业的一部分,但对分析感到困惑。
这是我的(工作)代码:
int shop(int m, int c, int items[][21], int sol[][20]) {
if (m < 0) return NONE; // No money left
if (c == 0) return 0; // No garments left
if (sol[m][c] != NONE) return sol[m][c]; // We've been here before
// For each model of the current garment
for (int i = 1; i <= items[c-1][0]; i++) {
// Save the result
int result = shop(m-items[c-1][i], c-1, items, sol);
// If there was a valid result, record it for next time
if (result != NONE) sol[m][c] = max(sol[m][c], result+items[c-1][i]);
}
return sol[m][c];
}
我在分析的几个方面遇到了麻烦:
我知道复杂性(根据Algorithmist)是O(M * C * max(K))其中K是每件衣服的模型数量,但我努力向后工作得到递归关系。这是我的猜测:
S(c)= k * S(c-1)+ 1,S(0)= 0
然而,这未考虑到M。
思想?
答案 0 :(得分:0)
您可以将每个DP状态(m,c)
视为图的顶点,其中对状态(m-item_i,c-1)
的递归调用是从(m,c)
到(m-item_i,i)
的边。
记忆递归意味着您只能从顶点开始搜索一次,并且只处理其传出边缘一次。因此,您的算法本质上是此图表上的线性搜索,并且具有复杂度O(|V|+|E|)
。有M * C个顶点,每个顶点最多max(K)
个边缘,因此您可以将边数限制为O(M*C*max(K))
。