UVA - 165(邮票)

 Stamps 

The government of Nova Mareterrania requires that various legal documents have stamps attached to them so that the government can derive revenue from them. In terms of recent legislation, each class of 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 analysed by government mathematicians who have derived a formula for n(h,k), where h is the number of stamps that may be attached to a document, k is the number of denominations of stamps available, and n is the largest attainable value in a continuous sequence starting from $1. For instance, if h=3, k=2 and the denominations are $1 and $4, we can make all the values from $1 to $6 (as well as $8, $9 and $12). However with the same values of h and k, but using $1 and $3 stamps we can make all the values from $1 to $7 (as well as $9). This is maximal, so n(3,2) = 7.

Unfortunately the formula relating n(h,k) to hk and 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 values of h and k, will determine an optimum set of stamps and the value of n(h,k).

Input

Input will consist of several lines, each containing a value for h and k. The file will be terminated by two zeroes (0 0). For technical reasons the sum of h and k is 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 value of h and k consisting of the k stamp values in ascending order right justified in fields 3 characters wide, followed by a space and an arrow (->) and the value of n(h,k) right justified in a field 3 characters wide.

Sample input

3 2
0 0

Sample output

1 3 -> 7

  对于这个题,我想多说点自己的东西,有关全排列的题目已经做了很多了,这个题是让我学到东西最多的,也让我明白了自己到底是有多弱。刚开始看到这个题时,并没有想到该怎么搜,后来想了很久,终于有了点头绪,因为要形成连续的value,所以必须要有1,但是有了1之后该怎么办呢,如果给了我K种denominations,那我第二种的范围该是什么,我们想想应该是[2 ... h + 1],为什么是从2开始呢?我也不知道,直觉,但是我能解释为什么到h + 1, 因为h个空,我可以都填上1,那么最大值就是h,如果我的第二种面值是h + 2,那么不可能连续,所以最大应该是h + 1。第三种面值与前面的类似,我就不多说了。所以这个题,我们该怎么做呢? 第一我们用一个dfs() 来找每种面值的可能值,那么用另一个dfs()来计算用这些面值能形成的所有可能值。当然求值的dfs()可以用完全背包的思想DP搞定。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4
 5 using namespace std;
 6
 7 int occur[1000];
 8 int stamp[10];
 9 int ans[10];
10 int h,k;
11 int maxn;
12 int maxValue[10];
13
14 // cur 表示用了多少张stamp,n表示种数,sum表示形成的和
15 void dfs(int cur,int n,int sum) {
16     if (cur > h) return;
17     occur[sum] = 1;
18     for (int i = 0;i <= n;i++) {
19         dfs(cur + 1,n,sum + stamp[i]);
20     }
21 }
22
23
24 // cur 表示种数
25 void work(int cur) { // cur is the kind of stamp;
26     if (cur == k) {
27         if (maxValue[cur - 1] > maxn) {
28             maxn = maxValue[cur - 1];
29             memcpy(ans,stamp,sizeof(stamp));
30         }
31     }
32     else {
33         for (int i = stamp[cur - 1] + 1;i <= maxValue[cur - 1] + 1;i++) {
34             stamp[cur] = i;
35             memset(occur,0,sizeof(occur)); // 每次求和的时候记得初始化
36             dfs(0,cur,0);
37             int num = 0;
38             while (occur[num + 1]) num++; //最大连续num
39             maxValue[cur] = num;
40             work(cur + 1);
41         }
42     }
43 }
44
45 int main () {
46     while (cin >> h >> k,k + h) {
47         stamp[0] = 1;
48         maxValue[0] = h;
49         maxn = 0;
50         work(1);
51         for (int i = 0;i < k;i++) {
52             printf("%3d",ans[i]);
53         }
54         printf(" ->%3d\n",maxn);
55     }
56 }

				
时间: 2024-10-07 01:51:18

UVA - 165(邮票)的相关文章

uva 165 Stamps (回溯)

uva 165 Stamps The government of Nova Mareterrania requires that various legal documents have stamps attached to them so that the government can derive revenue from them. In terms of recent legislation, each class of document is limited in the number

UVa 242 邮票和信封(完全背包)

https://vjudge.net/problem/UVA-242 题意: 输入s(每个信封能粘贴的最多邮票数量)和若干邮票组合,选出最大连续邮资最大的一个组合(最大连续邮资也就是用s张以内的邮票来凑1,2,3,4...n,如果无法凑成n+1,那么最大值也就是n了).如果有多个最大值,则优先考虑邮票数少的,其次考虑邮票面值最大的那个更小的. 思路: 完全背包问题. 完全背包是物品无限,在这里和题意相符合,每种邮票也是可以无限使用的.最大连续邮资就相当于一个背包容量,d[i]表示当最大连续邮资为

[题解]UVa 11082 Matrix Decompressing

开始眨眼一看怎么也不像是网络流的一道题,再怎么看也觉得像是搜索.不过虽然这道题数据范围很小,但也不至于搜索也是可以随随便便就可以过的.(不过这道题应该是special judge,因为一题可以多解而且题目中然而并没有什么要求,所以说可以考虑思考一下这道题有木有什么"套路"之类的通法) 比如说有这么一组数据 原矩阵 1 2 3 4 7 8 9 5 6 输入 3 3 6 25 45 14 28 45 然后将每一行的和写在每一列对应的行上(很明显有问题) 6 0 0 19 0 0 20 0

[题解]uva 1658 Admiral

vjudge传送门[here] 题目大意:给一个有(3≤v≤1000)个点e(3≤e≤10000)条边的有向加权图,求1~v的两条不相交(除了起点和终点外没有公共点)的路径,使权值和最小. 正解是吧2到v-1的每个点拆成两个点,中间连一条容量为1,费用为0的边,然后求1到v的流量为2的最小费用流就行了. Code 1 /** 2 * Uva 3 * Problem#1658 4 * Accepted 5 */ 6 #include<iostream> 7 #include<cstdio&

UVA 11324 The Largest Clique (强连通分量缩点,图DP)

题目: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=25&page=show_problem&problem=2299 题意: 给你一个有向图,求一个点集合的最大大小,使得此点集合中对于任意点对(u,v),有从u到v或者从v到u的边 方法: 先找强连通分量缩点,每个强连通分量显然满足条件,然后在缩点后的图中找到一条权值最大的路径,权值为此路径的点权之和,点权为这个

UVA 1146 Now or later

二分时间+2sat 边加多了....RE了好久...... Now or later Time Limit: 9000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu [Submit]   [Go Back]   [Status] Description As you must have experienced, instead of landing immediately, an aircraft sometimes waits

uva 704

自己之前的不见了.. 这题是双向广搜即可过.. 1 // Colour Hash (色彩缤纷游戏) 2 // PC/UVa IDs: 110807/704, Popularity: B, Success rate: average Level: 3 3 // Verdict: Accepted 4 // Submission Date: 2011-08-28 5 // UVa Run Time: 0.048s 6 // 7 // 版权所有(C)2011,邱秋.metaphysis # yeah

Fast Matrix Operations(UVA)11992

UVA 11992 - Fast Matrix Operations 给定一个r*c(r<=20,r*c<=1e6)的矩阵,其元素都是0,现在对其子矩阵进行操作. 1 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1<=x2,y1<=y2)子矩阵中的所有元素add上val: 2 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1<=x2,y1<=y2)子矩阵中的所有元素set为val: 3 x1 y1 x2 y2 val 表示输

UVa 568 Just the Facts

A过去后看了一下别人的解法,发现除了打表还有一种数论的方法. 分析一下阶乘后面的0是怎么出现的呢,当然是2乘5得到的. 我们将1~N先放在一个数组里面. 从数组第一个元素开始,先统计一下N!中因子为5的个数记为count,将其除去,然后再除去count个2.这样一来的话把所有元素乘起来后就不会出现10的倍数了. 当然并不是真正的乘起来,那样的话肯定是要溢出的,因为只关心最后一位数,所以每次乘完后求10的余数即可. 我的做法是打表,因为题目里给了N <= 10000的条件限制,所以可以把1~100