简化背包问题的递归算法与非递归算法

ch_lol 2005-09-09 08:40:18
觉得这两个算法比较经典
贴出来
大家讨论
感觉非递归的算法有点乱

/* 简化背包问题的递归算法*/

#include<stdio.h>
#include<stdlib.h>

int knap(int s, int n, int w[])
{
if ( s == 0 )
return (1);
else if ( s<0 || s>0 && n<1 )
return(0);
else if ( knap(s - w[n-1], n - 1, w)==1 )
{
printf("result: n=%d ,w[%d]=%d \n", n, n-1, w[n-1]);
return (1);
}
else
return ( knap(s, n - 1, w) );
}

int main() {
int* w;
int s = 0, n = 0, result = 0, i = 0;
printf("please input s = ");/*输入s*/
scanf("%d", &s);
printf("please input n = ");/*输入n*/
scanf("%d", &n);
w = (int*)malloc(n*sizeof(int));
printf("please input the %d numbers(weight):\n", n);/*输入重量*/
for (i = 0; i < n; i++)
scanf("%d", w+i);
result = knap(s, n, w);
if (result == 0)
printf("no solution!\n");
return 0;
}


/* 简化背包问题的非递归算法*/


#include<stdio.h>
#include<stdlib.h>
#define MAXNUM 20
#define TRUE 1
#define FALSE 0

struct NodeBag { /* 栈中元素的定义 */
int s , n ;
int r ; /* r的值为1,2,3 */
int k;
};

typedef struct NodeBag DataType;

struct SeqStack { /* 顺序栈类型定义 */
int t; /* 指示栈顶位置 */
DataType s[MAXNUM];
};

typedef struct SeqStack *PSeqStack; /* 顺序栈类型的指针类型 */

PSeqStack createEmptyStack_seq( void ) {
PSeqStack pastack;
pastack = (PSeqStack)malloc(sizeof(struct SeqStack));
if (pastack==NULL)
printf("Out of space!! \n");
else
pastack->t=-1;
return (pastack);
}

/* 在栈中压入一元素x */
void push_seq( PSeqStack pastack, DataType x ) {
if( pastack->t >= MAXNUM - 1 )
printf( "Overflow! \n" );
else {
pastack->t++;
pastack->s[pastack->t] = x;
}
}

/* 删除栈顶元素 */
void pop_seq( PSeqStack pastack ) {
if (pastack->t == -1 )
printf( "Underflow!\n" );
else
pastack->t--;
}

/* 当pastack所指的栈不为空栈时,求栈顶元素的值 */
DataType top_seq( PSeqStack pastack ) {
return pastack->s[pastack->t];
}

int nknap(int s, int n, int w[]) {
struct NodeBag x;
PSeqStack st;
int k;
st = createEmptyStack_seq( ); /* entry0: 初始调用入口 */
x.s = s; x.n = n; x.r = 1;
push_seq(st,x);
entry1: /* 递归调用入口 */
x = top_seq(st);
pop_seq(st); /* 该函数与后面最接近的一个push_seq函数对是为了完成修改栈顶元素 */
if (x.s == 0) {
x.k = TRUE;
push_seq(st,x);
goto exit2;
}
else if (x.s<0 || (x.s>0 && x.n<1)) {
x.k = FALSE;
push_seq(st,x);
goto exit2;
}
else {
push_seq(st,x); /* 由于此处需要进一步往下递归,所以需再次入栈 */
x.s = x.s - w[x.n-1];
x.n = x.n - 1;
x.r = 2;
push_seq(st, x);
goto entry1;
}
exit2: /* 返回处理 */
x = top_seq(st);
pop_seq(st);
switch (x.r) {
case 1:
free(st);
return(x.k);
case 2: goto L3;
case 3: goto L4;
}

L3: /* 继续处理1 */
if (x.k == TRUE) {
x = top_seq(st);
pop_seq(st);
x.k = TRUE;
push_seq(st,x);
printf("result n=%d , w=%d \n", x.n, w[x.n-1]);
goto exit2;
}
else {
x = top_seq(st);
x.s = x.s;
x.n = x.n - 1;
x.r = 3;
push_seq(st,x);
goto entry1;
}
L4: /* 继续处理2 */
k = x.k;
x = top_seq(st);
pop_seq(st);
x.k = k;
push_seq(st,x);
goto exit2;
}

int main() {
int* w;
int s = 0, n = 0, result = 0, i = 0;

printf("please input s = ");/*输入s*/
scanf("%d", &s);
printf("please input n = ");/*输入n*/
scanf("%d", &n);
w = (int*)malloc(n*sizeof(int));
printf("please input the %d numbers(weight):\n", n);/*输入重量*/
for (i = 0; i < n; i++)
scanf("%d", w+i);
result = nknap(s,n, w);
if (result == 0)
printf("no solution!\n");
return 0;
}
...全文
350 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
foochow 2005-09-09
  • 打赏
  • 举报
回复
第二个不用那么复杂吧......

64,683

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧