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 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 h,
k 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

题目大意:每组样例有两个数据:h和k(以(0,0)为样例终点)。h为可以贴的邮票上限,k为邮票的所给的面额的种类。要求用k种  1~h张邮票所能组成的最长连续序列(从一开始)。

解题思路:两层回溯,第一层找出k张邮票不同面额的搭配方式,第二层找出当前搭配方式所能组成的最长连续序列。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int h, k, ans, temp, num[200], num2[200], vis[200], flag;

void DFS2(int sum, int result, int step) {  //检验当前不同面额能否组成result
	if (flag) return;
	if (sum == result) {
		flag = 1;
		return;
	}
	if (step == h) return;
	for (int i = 0; i < k; i++) {
		sum += num[i];
		DFS2(sum, result, step + 1);
		sum -= num[i];
	}
}

void DFS(int step) {
	if (step == k) {
		 temp = h;
		do {                    //找出当前面额情况所能组成的最长连续序列
			flag = 0;
			temp++;
			DFS2(0, temp, 0);
		} while (flag);

		if (temp - 1 > ans) {
			ans = temp - 1;
			for (int i = 0; i < k; i++) {
				num2[i] = num[i];
			}
		}
		return;
	}
	for (int i = num[step - 1]; i <= temp + 7; i++) {  //回溯找出不同的面额搭配方式
		if (!vis[i] && i > num[step - 1]) {
			vis[i] = 1;
			num[step] = i;
			DFS(step + 1);
			vis[i] = 0;
		}
	}
}

int main() {
	while (scanf("%d %d", &h, &k) == 2, h || k) {
		ans = 0;
		memset(vis, 0, sizeof(vis));
		memset(num, 0, sizeof(num));
		memset(num2, 0, sizeof(num2));
		flag = 0;
		num[0] = 1;
		vis[1] = 1;
		temp = h;

		DFS(1);

		for (int i = 0; i < k; i++) {   //注意输出格式
			printf("%3d", num2[i]);
		}
		printf(" ->%3d\n", ans);
	}
	return 0;
}
时间: 2024-08-10 00:06:46

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 of st

UVa 242 Stamps and Envelope Size (无限背包,DP)

题意:信封上最多贴S张邮票.有N个邮票集合,每个集合有不同的面值.问哪个集合的最大连续邮资最 大,输出最大连续邮资和集合元素. 最大连续邮资是用S张以内邮票面值凑1,2,3...到n+1凑不出来了,最大连续邮资就是n.如果不止一个集合结果相 同,输出集合元素少的, 如果仍相同,输出最大面值小的. 析:这个题,紫书上写的不全,而且错了好几次,结果WA好几次. 首先这个和背包问题差不多,我们只用一维就好.dp[i]表示邮资为 i 时的最小邮票数,然后,如果dp[i] > s就该结束了. 其他的就很简

UVa 242 - Stamps and Envelope Size(DP)

给出一个s,然后给出n组邮票,问那一组可以凑出最大连续邮资. 对每一组邮票,求出当邮资为i时需要邮票数的最小值d[i],边界为d[0]=0.d[i]>s时break.类似于背包问题的求法,具体方法见代码. #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=1010; int d[maxn],ans[20],num[20],a[20][

UVA题目分类

题目 Volume 0. Getting Started 开始10055 - Hashmat the Brave Warrior 10071 - Back to High School Physics 10300 - Ecological Premium 458 - The Decoder 494 - Kindergarten Counting Game 414 - Machined Surfaces 490 - Rotating Sentences 445 - Marvelous Mazes

UVA Stamps

题目如下: Stamps  The government of Nova Mareterrania requires that various legaldocuments have stamps attached to them so that the government canderive revenue from them. In terms of recent legislation, each classof document is limited in the number of

UVA - 524 Prime Ring Problem(dfs回溯法)

UVA - 524 Prime Ring Problem Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Description A ring is composed of n (even number) circles as shown in diagram. Put natural numbers  into each circle separately, and the sum of number

uva 11218 KTV(DFS+回溯)

uva 11218 KTV One song is extremely popular recently, so you and your friends decided to sing it in KTV. The song has 3 characters, so exactly 3 people should sing together each time (yes, there are 3 microphones in the room). There are exactly 9 peo

uva 639 Don&#39;t Get Rooked (暴力回溯 )

uva 639 Don't Get Rooked In chess, the rook is a piece that can move any number of squares vertically or horizontally. In this problem we will consider small chess boards (at most 44) that can also contain walls through which rooks cannot move. The g

uva 639 Don&#39;t Get Rooked ( 回溯 )

这道题确实是标准的回溯,果然还是早上比较清醒一些,昨天晚上想了好长一会儿都没有想起来,早上一会的功夫就A 了,估计也有昨天晚上的帮助...总感觉不想写太多私人的东西在这上面,因为这个是每个人都可以无条件访问的... 思路: 由于数据比较小,可以把每个元素都遍历一遍,回溯选择,最多4*4,还是很小的,我交的才1ms,1A.. 贴代码: #include<stdio.h> #include<string.h> #include<stdlib.h> int map[10][1