Should be the Usaco topic, temporarily did not find the corresponding source.
"The main topic"
The farmer John wants to take the Q (1 <= q <= 20,000) quart (quart, quarts, Volume Unit--translator note) His best milk and put it into a large bottle to sell. The consumer wants how much, he gives how much, never has any error.
Farmer John is always frugal. He now buys some barrels in the dairy hardware store to measure the Q-quart of milk from his huge pool of milk. The price of each barrel is the same. Your task is to figure out a collection of the fewest buckets that a farmer John can buy, making it possible to use these buckets to measure the milk of the Q-quart. In addition, since the farmer John had to move the barrels home, he would choose the "smaller" one for the two minimum buckets given, namely:
Sort the two collections in ascending order, compare the first bucket, and choose the one with the smaller volume of the first bucket. If the first bucket is the same, compare the second bucket and choose the method as above. Otherwise, continue this work until the two buckets in the comparison are not consistent. For example, the collection {3,5,7,100} is better than the collection {3,6,7,8}.
In order to measure the milk, farmer John could fill the pail from the Milk pond and pour it into the bottle. He would never pour the milk out of the bottle or pour the milk from the pail elsewhere. With a bucket of 1 quarts, farmer John could use the bucket to measure out all the possible quart counts. The other buckets are not so convenient. Calculate the best bucket set to buy, ensuring that all test data has at least one solution.
INPUT FORMAT
Line 1: An integer Q
Line 2: An integer p (1 <= p <= 100) indicating the number of buckets in the store
Lines 3..p+2: The volume of each row including a barrel (1 <= barrels of volume <= 10000)
OUTPUT FORMAT
The output file has only one row, consisting of integers separated by spaces:
In order to measure the desired number of quarts, the minimum quantity of barrels to be purchased, followed by:
A well-ordered list (small to large) that represents the volume of each bucket that needs to be purchased
SAMPLE INPUT
16
3
3
5
7
SAMPLE OUTPUT
2 3 5
Ideas
Deep Search can, first of the bucket to the volume size of the keyword in ascending order. For the current state of Barrel,step,sum (the latest bucket taken, the number of barrels already bought, the total volume has been taken). Each time you can choose to use the latest bucket has been taken to continue to take or take a volume than the volume of barrels already large.
Exits if the current number of buckets is already greater than the minimum number of buckets;
If the volume to be taken is currently reached and the number of buckets is less than or equal to the minimum number of barrels, then the update is made.
"Error Point"
At first I wrote an if (Step==minp && sum<q) return for pruning, but it was wrong because the current bucket could continue to be loaded. For example, the following sample input, if added to this statement (3,5) will be abandoned.
1#include <iostream>2#include <cstdio>3#include <algorithm>4 using namespacestd;5 intQ,p;//Q is the total volume, p is the number of barrels in the store6 Const intmaxn=10000+ -;7 intV[MAXN],MINN[MAXN],NOW[MAXN];8 intminp,nowp;9 Ten intCheck () One { A for(intI=0; i<minp;i++) - if(Now[i]!=minn[i])return(now[i]<minn[i]); - } the - voidDfsintBarrel,intStepintSum//taken to the first few barrels, had bought a few barrels, had reached the volume of - { - if(STEP>MINP)return; + /*if (step==minp && sum<q) return; This sentence is wrong, because the same bucket can continue to be removed*/ - if(sum==q) && (step==minp && check () | | step<minp)) + { Aminp=Step; at for(intI=0; i<step;i++) minn[i]=Now[i]; - } - if(barrel!=-1&& sum+v[barrel]<=q) - { -DFS (barrel,step,sum+V[barrel]); - } in /*If the current bucket can continue to be used, continue deep search*/ - for(inti=barrel+1; i<p;i++) to { + if(sum+v[i]<=q) - { thenow[nowp]=V[i]; *nowp++; $ /*nowp++ to write in now[nowp]=v[i], otherwise nowp is not starting from 0*/ Panax NotoginsengDFS (i,step+1, sum+v[i]); -nowp--; the } + } A } the + intMain () - { $Freopen ("Mr353.in4","R", stdin); $Freopen ("Mr353.ou4","W", stdout); -scanf"%d%d",&q,&p); - for(intI=0; i<p;i++) scanf ("%d",&v[i]); theSort (v,v+p); - Wuyiminp=MAXN; theDFS (-1,0,0); - Wucout<<minp<<' '; - for(intI=0; i<minp-1; i++) cout<<minn[i]<<' '; Aboutcout<<minn[minp-1]<<Endl; $ - return 0; -}
"Depth-first search" mr353-milk intake