自学算法从入门到放弃:递归.满背包问题

    /**********************递归.2*************************/
例题二:
    背包问题:一背包只能装V体积的物体。现在有N个物品,第i件占V[i]体积。
    现在要求:如果其中n0件物品能恰好装满背包,则输出这一个组合;
          如果没有满足的组合则输出false。
算法分析:
    *回溯法:
        1.首先将所有物品按照升序排序;(升序为了降低时间复杂度)
        2.再先将第1个物品放入背包,如果背包未满则放下一个物品;
        3.当放入第i个背包时候,背包体积超出限制,则将上一个物品拿出
          并跳过该拿出的物品,将下一个物品放入背包。重复这一操作,并
          输出所有满足的组合;
        4.如果放入背包的物品是最后一个则先判断是否有输出,若没有则输
          出false。

/*注释:ascending sort -- 升序排列
		backdata -- 回溯	   */
		#include 
	int data[1000];
	int print[1000]={0};
	int n;
	int flag=0;/*输出指示*/
	//backdata,maxmenber count <= 1000
	//ascending sort :为了方便,这里就用冒泡实现升序
	void sort(int data[])
	{
		int i,j,t;
		for(i=0;i < n;i++)
		{
			for(j=i;j < n;j++)
			{
				if(data[i] > data[j])
				{
					t=data[i];
					data[i]=data[j];
					data[j]=t;
				}
			}
		}
	}
	//print the group
	void prin(int k)
	{
		printf("可实现组合%d:\n",flag); 
		int i;
		for(i=0;i <= k;i++)
		printf("%d ",print[i]);
		printf("\n");
	}
	//the mainly function
	int backdata(int i,int k,int last)
	{
		int j,f;
		if(last - data[i] < 0)
		return 2;
		if(last - data[i] == 0)
		{
			flag++;
			print[k]=data[i];
			prin(k);
			return 1;
		}
		if(last - data[i] > 0)
		print[k]=data[i];
		for(j=i+1;j < n;j++){
			f=backdata(j,k+1,last - data[i]);
			if(f == 2 || f == 1)
			break;
		}
		return 0;	
	}
	int main()
	{
		int i,j,f,bag;
		printf("请输入个数n和背包最大容积;\n");
		scanf("%d%d",&n,&bag);
		printf("请输入各个物品的体积:\n");
		for(i=0;i < n;i++)
		scanf("%d",&data[i]);
		sort(data);
		for(j=0;j < n;j++)
		{
			f=backdata(j,0,bag);
			if(f == 2)
			break;
		}
		if(flag == 0)
		printf("false\n");
		return 0;
	}

 

你可能感兴趣的:(入门的,基础算法,C语言入门学习与巩固)