您的位置:首页 > 编程语言 > C语言/C++

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

2016-11-15 13:48 267 查看
一、题目描述

试管

时间限制: 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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐