一、题目描述
试管
时间限制: 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;
}
}