试管----朴素的递归算法----简直就是枚举

一、题目描述

试管

时间限制: 1 Sec  内存限制: 128 MB

题目描述

有 n 只试管,每个试管有一定的体积 vi,现在要量出 m 体积的液体,请问最少需要多少支试

管,并将试管的体积从小到大依次输出。因为可能有许多种方案,请输出一个字典序最小的方

案。( 如果你有一个 1 体积的试管,就可以量出任意体积的液体 )

输入

第一行一个整数 m,表示要量取的液体体积。(1<=m<=20000)

第二行一个整数 n,表示试管的数量。(1<=n<=100)

第三到第 n+2 行,每行一个整数,表示每个试管的体积 vi。(1<=vi<=10000)

输出

第一行一个整数 x,表示最少需要的试管数

第二行,x 个空格分隔开的整数,表示符合条件的一个字典序最小的方案,要求从小到大排序。

样例输入

16

3

3

5

7

样例输出

2
3 5

提示

输出的试管编号按体积大小从小到大的字典序输出


二、分析

看到这道题就觉得非常无语……….

写了两天代码之后,终于AC了!

虽然不是正解(因为数据太水),但是思路比较简单,

(1)输入,对试管大小进行排序

(2)利用for()来枚举最终的试管数量

(3)在for()里写dfs()来枚举每一个试管水量

(3)在dfs()里写pd()来判断这一组试管是否能达到要求(正解是用背包判断)

(4)达到要求就使f=1,退出所有函数,进行输出

(5)达不到要求就继续搜索

好了,代码如下:

#include<cstdio>
#include<algorithm>
using namespace std;
int a[105],n,m,p[105],x,o,f,sum;
void pd(int q)
{
	if(q>o){
		if(sum==m)
			f=1;
		return;
	}
	for(int i=1;i<=x;i++){
		sum+=i*p[q];
		pd(q+1);
		sum-=i*p[q];
		if(f==1)
			break;
	}
}
void dfs(int s,int q)
{
	if(s==0){
		sum=0;
		f=0;
		pd(1);
		if(f==1){
			printf("%d\n",o);
			for(int i=1;i<=o;i++){
				if(i==1)
					printf("%d",p[i]);
				else
					printf(" %d",p[i]);
			}
		}
	}
	else{
		for(int i=q;i<=n-s+1;i++){
			if(q==1) x=m/a[i];
			o++;
			p[o]=a[i];
			dfs(s-1,i+1);
			o--;
			if(f==1)
				break;
		}
		if(f==1)
			return;
	}
}
int main()
{
	int i,j;
	scanf("%d%d",&m,&n);
	for(i=1;i<=n;i++)
		scanf("%d",&a[i]);
	sort(a+1,a+n+1);
	f=0;
	for(i=1;i<=n;i++){
		o=0;
		dfs(i,1);
		if(f==1)
			return 0;
	}
}


    原文作者:递归算法
    原文地址: https://blog.csdn.net/C20180602_csq/article/details/53170495
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞