【发布时间】:2015-04-02 18:43:17
【问题描述】:
所以我一直在尝试解决子集和问题的一个变体,我想使用动态编程来解决这个问题。所以我的目标是,例如,输入
m = 25 // Target value
n = 7 // Size of input set
输入设置为例如{1, 3, 4, 6, 7, 10, 25}。所以想要的输出类似于
{1, 3, 4, 7, 10} and {25}.
这里是代码
#include <stdio.h>
#include <stdlib.h>
int main()
{
// Get input sequence
int n = 7; // Size of input set
int m = 25; // Target value
int *S; // Input set
int **C; // Cost table
int i,j,potentialSum,leftover;
S=(int*) malloc((n+1)*sizeof(int));
C=malloc((m+1)*sizeof(int*));
for (int rows = 0; rows<=m; rows++) {
C[rows] = malloc((m+1)*sizeof(int));
}
if (!S || !C)
{
printf(" FAILED %d\n",__LINE__);
exit(0);
}
S[0] = 0;
S[1] = 1;
S[2] = 3;
S[3] = 4;
S[4] = 6;
S[5] = 7;
S[6] = 10;
S[7] = 25;
// Initialize table for DP
C[0][0]=0; // DP base case
// For each potential sum, determine the smallest index such
// that its input value is in a subset to achieve that sum.
for (potentialSum=1; potentialSum<=m; potentialSum ++)
{
for (j=1;j<=n;j++)
{
leftover=potentialSum-S[j]; // To be achieved with other values
if (leftover<0) // Too much thrown away
continue;
if (C[leftover][0] == (-1)) // No way to achieve leftover
continue;
if (C[leftover][0]<j) // Indices are included in
break; // ascending order.
}
C[potentialSum][0]=(j<=n) ? j : (-1);
}
// Output the input set
printf(" i S\n");
printf("-------\n");
for (i=0;i<=n;i++)
printf("%3d %3d\n",i,S[i]);
// Output the DP table
printf("\n\n i C\n");
printf("-------\n");
for (i=0;i<=m;i++)
printf("%3d %3d\n",i,C[i][0]);
if (C[m][m]==(-1))
printf("No solution\n");
else
{
printf("\n\nSolution\n\n");
printf("(Position) i S\n");
printf("------------------\n");
for (i=m;i>0;i-=S[C[i][0]])
printf(" %3d %3d\n",C[i][0],S[C[i][0]]);
}
}
这将输出以下内容
i S
-------
0 0
1 1
2 3
3 4
4 6
5 7
6 10
7 25
i C
-------
0 0
1 1
2 -1
3 2
4 2
5 3
6 4
7 3
8 3
9 4
10 4
11 4
12 5
13 4
14 4
15 5
16 5
17 5
18 5
19 6
20 5
21 5
22 6
23 6
24 6
25 6
Solution
(Position) i S
------------------
6 10
5 7
3 4
2 3
1 1
Program ended with exit code: 0
我的问题是我只能输出一个解决方案,即需要较小值并达到 25 的解决方案,所以当使用 25 时,它不在解决方案中。代码中的C 数组是一个二维数组,因为我认为我可以在计算第一个回溯时进行另一个回溯?我不知道该怎么做,所以我将C[i][0] 固定在第一列,只是为了演示一个解决方案。任何正确方向的提示将不胜感激。我找到了一个使用 Python 的解决方案,但问题是递归解决的,我认为这对我没有帮助,但该代码是 here。
提前感谢所有帮助。
【问题讨论】:
-
请不要发布代码和输出的链接。如果这些链接断开,则此处发布的 cmets 和答案将毫无意义。在问题本身中发布代码和输出。
-
@RSahu 抱歉,感谢您的提醒。
标签: c dynamic-programming backtracking subset-sum