165-stamps, continuous postage

Source: Internet
Author: User
165-stamps 2611 35.85% 879 77.59%

Question link:

Http://uva.onlinejudge.org/index.php? Option = com_onlinejudge & amp; Itemid = 8 & amp; Category = 108

Type: backtracking

Original question:

The Government of Nova mareterrania requires that various legal related Ents have stamps attached to them so that the Government can derive revenue from them. In terms of recent legislation, each class
Document is limited in the number of stamps that may be attached to it. the Government wishes to know how many different stamps, and of what values, they need to print to allow the widest choice of values to be made up under these conditions. stamps are always
Valued in units of $1.

This has been analyzed by government mathematicians who have derived a formulaN(H,K), WhereHIs the number of stamps that may be attached to a document,KIs
The number of denominations of stamps available, andNIs the largest attainable value in a continuous sequence starting from $1. For instance, ifH= 3,K= 2 and the denominations are $1 and $4, we can make all the values from $1
$6 (as well as $8, $9 and $12). However with the same valuesHAndK, But using $1 and $3 stamps we can make all the values from $1 to $7 (as well as $9). This is maximal, soN(3, 2) = 7.

Unfortunately the formula relatingN(H,K)H,KAnd the values of the stamps has been lost -- it was published in one of the government reports but no-one can
Remember which one, and of the three researchers who started to search for the formula, two died of boredom and the third took a job as a lighthouse keeper because it provided more social stimulation.

The task has now been passed on to you. You doubt the existence of a formula in the first place so you decide to write a program that, for given valuesHAndK, Will determine an optimum
Set of stamps and the valueN(H,K).

Input

Input will consist of several lines, each containing a valueHAndK. The file will be terminated by two zeroes (0 0). For technical reasons the sumHAndKIs
Limited to 9. (The President lost his little finger in a shooting accident and cannot count past 9 ).

Output

Output will consist of a line for each valueHAndKConsisting ofKStamp values in ascending order right justified in fields 3 characters wide, followed by a space and
An arrow (->) And the valueN(H,K) Right justified in a field 3 characters wide.

Sample Input

3 20 0

Sample output

  1  3 ->  7

Question:

A country issues K kinds of stamps with different denominations, and requires that each envelope can only contain up to H stamps. The formula n (H, k) indicates that H stamps are selected from the stamps with the nominal values in K to form a continuous 1, 2, 3 ,...... N and n are the sum of the largest possible nominal values. For example, when H = 3, K = 2, assuming the two nominal values are, they can form a continuous 1 ...... 6. Although they can be 8, 9, and 12, they are not continuous.

Analysis and Summary:

Continuous postage is a classic problem. Wang Xiaodong introduced p173, the third edition of computer algorithm design and analysis, but not detailed enough. Here I reposted a blog to give a more in-depth and detailed analysis of Wang Xiaodong's lecture:

Continuous postage problem http://blog.csdn.net/shuangde800/article/details/7755254


The following is a summary based on my own words:


First, open an array stampval [0... I] to save each face value, and then open a maxval [0... I] to save the maximum continuous face value that can be composed of all the current face values.

Then, we can determine that stampval [0] must be equal to 1. If there is no 1, many numbers cannot be merged.

Then, maxval [0] = 1 * H. H indicates the number of stamps allowed.

The next step is to determine the face value of the second and third stamps?

For stampval [I + 1], the value range is stampval [I] + 1 ~ Maxval [I] + 1.

Stampval [I] + 1 is better understood. The value of this operation must be larger than that of the previous operation, the upper limit of the face value obtained this time is the maximum consecutive face value that can be reached last time + 1, because if it is larger than this

A fault occurs, that is, the maximum face value + 1 of the last time cannot be formed. For example, assume that three stamps can be pasted with three denominations. The first two denominations have been determined to be 1, 2, and the maximum sequential denominations can be 6, the value range of the next 3rd kinds of face values is 3 ~ 7. What if we get bigger than 7? Let's get it done. If we take 8, the nominal values are 1, 2, 8, and cannot be combined into 7 !!


After knowing this, we can understand the general idea of backtracking, but it is not enough. How can we obtain the maximum continuous nominal values that can be achieved by a given number of nominal values?

The most intuitive and easy to think of is to recursively trace back all the situations to know the maximum continuous value.

The recursive functions I wrote are as follows:

// The number of tickets used by cur. The sum of N and sum is void DFS (INT cur, int N, int sum) {If (cur> = H) {occur [Sum] = true; return;} occur [Sum] = true; For (INT I = 0; I <= N; ++ I) {DFS (cur + 1, n, sum + stampval [I]) ;}}

Occur is a global array. It is initialized to 0 when recursion is called. Then, it is used to record the sum of the appeared face values.

At last, you only need to start enumeration from the subscript 1 of the occur array until the maximum continuous nominal value can be reached when the value is not true.



Because the data size of this question is small, it will not time out at all, and the speed is good:

165-stamps Accepted C ++ 0.068

The following code uses this method:

# Include <cstring> # include <cstdio> # include <cstdlib> # include <iostream> # define maxn 200 using namespace STD; int H, K; int ans [maxn], maxstampval, stampval [maxn], maxval [maxn]; bool occur [maxn]; // calculate the maximum continuous nominal value that can be achieved by the given denomination and quantity. // The number of tickets used by cur, the number of current denominations, and the sum of sum denominations void DFS (INT cur, int N, int sum) {If (cur> = h) {occur [Sum] = true; return;} occur [Sum] = true; For (INT I = 0; I <= N; ++ I) {DFS (cur + 1, n, sum + stampval [I]) ;}} void search (INT cur) {If (cur> = k) {If (maxval [cur-1]> maxstampval) {maxstampval = maxval [cur-1]; memcpy (ANS, stampval, sizeof (stampval);} return ;}for (INT I = stampval [cur-1] + 1; I <= maxval [cur-1] + 1; ++ I) {memset (occur, 0, sizeof (occur); stampval [cur] = I; DFS (0, cur, 0); int num = 0, j = 1; while (occur [J ++]) ++ num; maxval [cur] = num; search (cur + 1) ;}} int main () {# ifdef local freopen ("input.txt", "r", stdin); # Number of endif // H, number of K denominations while (scanf ("% d ", & H, & K), H + k) {stampval [0] = 1; maxval [0] = H; maxstampval =-2147483645; search (1 ); for (INT I = 0; I <K; ++ I) printf ("% 3d", ANS [I]); printf ("-> % 3d \ n ", maxstampval);} return 0 ;}


Calculating the maximum continuous postage interval of X [1: I] is frequently used in this algorithm. If the data volume is large, it is likely to time out.

The third edition of computer algorithm design and analysis provides a more efficient method:

Considering that the complexity of direct recursion is too high, we may try to calculate the X [1: i] the minimum number of stamps required for postage K is Y [K]. You can use y [k] to quickly release the R value. In fact, Y [k] can be solved by recursion within O (n) Time:

For (Int J = 0; j <= x [I-2] * (S-1); j ++)
If (Y [J] <m)
For (int K = 1; k <= m-y [J]; k ++)
If (Y [J] + k <Y [J + X [I-1] * k]) y [J + X [I-1] * k] = Y [J] + K;
While (Y [R] <maxint) r ++;

The blog post reposted has a more in-depth analysis of this Article.


165-stamps Accepted C ++ 0.016

The speed has been significantly improved.


The following code is as follows:

# Include <cstring> # include <cstdio> # include <cstdlib> # include <iostream> # define INF 2147483647 # define maxn 2000 using namespace STD; int H, K; int ans [maxn], maxstampval, stampval [maxn], maxval [maxn], Y [maxn]; bool occur [maxn]; void search (INT cur) {If (cur> = k) {If (maxval [cur-1]> maxstampval) {maxstampval = maxval [cur-1]; memcpy (ANS, stampval, sizeof (stampval);} return;} int TMP [maxn]; memcpy (TMP, Y, sizeof (y )); for (INT I = stampval [cur-1] + 1; I <= maxval [cur-1] + 1; ++ I) {stampval [cur] = I; // key steps, using the dynamic planning idea for (Int J = 0; j <stampval [cur-1] * h; ++ J) if (Y [J] 

-- The meaning of life is to give it meaning.

 

Original Http://blog.csdn.net/shuangde800 , By d_double(For details, refer)




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.