vijosP1159 岳麓山上打水

 

链接:https://vijos.org/p/1159

 

【思路】

   迭代加深搜索+完全背包判断。

   自己没有思路,看的别人代码。

   总体上讲就是不断增大桶的数目并以之为上界搜索,用DP判断搜索是否可行。貌似数据很水所以可以较快通过。

   其中DFSID(cur+1,dep)很奇妙,如果改成取i从0到n的搜索的话会TLE。

 

【代码】

 

 

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 100+10;
 8 
 9 int dp[20010];
10 int ans[maxn],a[maxn];
11 int n,q,max_d;
12 
13 int check(int sum)
14 {
15     int &cur=dp[sum];
16     if(cur != -1) return cur;
17     if(sum==0) return cur=1;
18     else 
19     {
20         for(int i=0;i<max_d;i++)
21           if(sum>=ans[i] && check(sum-ans[i]))
22              return cur=1;
23     }
24     return cur=0;
25 }
26 
27 void DFSID(int cur,int dep) {
28     if(dep==max_d)                   //到达深度限制判断是否能够组成q 
29     {
30         memset(dp,-1,sizeof(dp));
31         if(check(q))
32         {
33             cout<<max_d<<" ";
34             for(int i=0;i<dep;i++) cout<<ans[i]<<" ";
35             exit(0);
36         }
37         return ;  //return 
38     }
39     
40     if(cur>=n) return ;
41     
42     ans[dep]=a[cur];
43     DFSID(cur+1,dep+1);
44     DFSID(cur+1,dep);   //一个不错的写法 
45 }
46 
47 int main() {
48     ios::sync_with_stdio(false);
49     
50     cin>>q>>n;
51     for(int i=0;i<n;i++) cin>>a[i];
52     
53     sort(a,a+n);         //字典序要求最小 
54     
55     for(max_d=1;max_d<=n;max_d++)
56        DFSID(0,0);
57     
58     return 0;
59 }