luogu P1494 岳麓山上打水 [iddfs]

题目描述

今天天气好晴朗,处处好风光,好风光!蝴蝶儿忙啊,蜜蜂也忙,信息组的同学们更加忙。最近,由于XX原因,大家不得不到岳麓山去提水。55555555~,好累啊。

信息组有一个容量为q升的大缸,由于大家都很自觉,不愿意浪费水,所以每次都会刚好把缸盛满。但是,信息组并没有桶子(或者瓢)来舀水,作为组内的生活委员,你必须肩负重任,到新一佳去买桶子。

新一佳有p种桶子,每种桶子都有无穷多个^_^,且价钱一样。由于大家都很节约,所以你必须尽量少买桶子。如果有多种方案,你必须选择“更小”的那种方案,即:把这两个方案的集合(不同大小的桶子组成)按升序排序,比较第一个桶,选择第一个桶容积较小的一个。如果第一个桶相同,比较第二个桶,也按上面的方法选择。否则继续这样的比较,直到相比较的两个桶不一致为止。例如,集合{3,5,7,三} 比集合 {3,6,7,8} 要好。

为了把缸装满水,大家可以先从岳麓山的井里把桶装满水提回来,然后倒进缸里。为了不十分麻烦或者浪费宝贵的水资源,大家决不把缸里的水倒出来或者把桶里的水倒掉,也不会把桶里的水再倒回井中,(这样会污染井水)。当然,一个桶可以使用多次。例如,用一个容积为 1 升的桶可以将任意容量的大缸装满水。而其它的组合就要麻烦些。

输入输出格式

输入格式:

第1行1个数q(q<=20000)。

第2行1个数p(p<=100)。

接下来p行,每行一个数,依次为每个桶的容积。

输出格式:

共1行,每两个数间用空格分隔,第1个数k为最少的桶的数量,接下来k个数从小到大输出每个桶的容量。

输入输出样例

输入样例#1:
16
3
3
5
7
输出样例#1:
2 3 5

My Solution

不加启发式搜索的迭代加深第一题

用k限定答案上界

感谢csdn博客MyCodeBattle给我的代码启发

luogu里同样是迭代加深各个的速度差好多  QwQ

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 inline int read(){
 8     char ch;
 9     int re=0;
10     while((ch=getchar())<'0'||ch>'9');
11     re=ch-'0';
12     while((ch=getchar())>='0'&&ch<='9')  re=re*10+ch-'0';
13     return re;
14 }
15 
16 const int maxq=20001,maxn=101;
17 int data[maxn];
18 int q,n;
19 int dp[maxq],ans[maxn];
20 int k;
21 
22 void init(){
23     q=read(),n=read();
24     for(int i=0;i<n;i++)
25         data[i]=read();
26     sort(data,data+n);
27 }
28 
29 bool check(int sum){
30     int &cur=dp[sum];
31     if(cur!=-1)
32         return cur;
33     if(sum==0)
34         return cur=1;
35     for(int i=0;i<k;i++)
36         if(sum>=ans[i]&&check(sum-ans[i]))
37             return cur=1;
38     return cur=0;
39 }
40 
41 void iddfs(int cur,int depth){
42     if(depth==k){
43         memset(dp,-1,sizeof dp);
44         if(check(q)){
45             printf("%d",k);
46             for(int i=0;i<depth;i++)
47                 printf(" %d",ans[i]);
48             printf("
");
49             exit(0);
50         }
51         return;
52     }
53     if(cur>=n)
54         return;
55     ans[depth]=data[cur];
56     iddfs(cur+1,depth+1);
57     iddfs(cur+1,depth);
58 }
59 
60 void solve(){
61     for(k=1;k<=n;k++)
62         iddfs(0,0);
63 }
64 
65 int main(){
66     init();
67     solve();
68     return 0;
69 }

也许我没有天分  但我有梦的天真  我将会去证明用我的一生

原文地址:https://www.cnblogs.com/ZYBGMZL/p/6856700.html