UVA 165 (13.07.29)

 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 stamps that may be attached toit. The government wishes to know how many different stamps, and ofwhat values, they need to print to allow the widest choice of valuesto be made up under these conditions. Stamps are always valued inunits of $1.

This has been analysed by government mathematicians who have derived aformula forn(h,k), where h is the number of stamps that may beattached to a document,k is the number of denominations of stampsavailable, and n is the largest attainable value in a continuoussequence starting from $1. For instance, ifh=3, k=2 and thedenominations 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 ofhand k, 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 relating n(h,k) to h,k and the values ofthe stamps has been lost--it was published in one of the governmentreports but no-one can remember which one, and of the threeresearchers who started to search for the formula, two died of boredomand the third took a job as a lighthouse keeper because it providedmore social stimulation.

The task has now been passed on to you. You doubt the existence of aformula in the first place so you decide to write a program that, forgiven values ofh and k, will determine an optimum set of stamps andthe value ofn(h,k).

Input

Input will consist of several lines, each containing a value for h andk. The file will be terminated by two zeroes (0 0). For technicalreasons the sum ofh and k is limited to 9. (The President lost hislittle 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 ofthek stamp values in ascending order right justified in fields 3characters wide, followed by a space and an arrow (->) and the valueofn(h,k) right justified in a field 3 characters wide.

Sample input

3 2
0 0

Sample output

  1  3 ->  7

题意: 给出h个贴邮票的位置, 给出k种面值的邮票, 求由这k种邮票能组合成的邮资, 最多可连续到多少(注意, 是连续!)
例如, 3个位置, 2种面值, 面值为1, 2
那么可组成1, 2, 3, 4, 5, 6价值的邮资, 答案为6
但是, 面值若取1, 3
那么可组成1, 2, 3, 4, 5, 6, 7, 9价值的邮资, 答案为7
可以证明, 在h=3, k=2时, 邮资最大可连续到7, 答案为7, 不是6!

做法中的注意点:
首先, 总邮资为1肯定要有, 所以, 面值为1的邮票要取
那么在选下一张邮票的面值时, 要注意, 取的过大, 则中间某价值的邮资拼不出来, 若取小了, 又得不到最大连续邮资~
不过, 还好的是, 取值范围可以推出, 设Stamp数组, 下标代表第i张, 数值代表第i张邮票面值, 设max数组, 下标代表第i张, 数值代表到第i张时, 总面值多少
那么 Stamp[i]+1 <= Stamp[i+1] <= max[i]+1

接下来就是回溯搞定了~

AC代码:
#include<stdio.h>
#include<string.h>

int h, k, Max;
int stamp[10];
int max[10];
int ans[10];
int can[200];

void dfs(int pos, int count, int cur_max) {
	if(pos > h)
		return ;
	can[cur_max] = 1;
	for(int i = 1; i <= count; i++) 
		dfs(pos+1, count, cur_max+stamp[i]);
}

void search(int count) {
	int value;
	if(count >= k) {
		if(max[count] > Max) {
			Max = max[count];
			for(int i = 1; i <= k; i++)
				ans[i] = stamp[i];
		}
		return ;
	}
	for(int i = stamp[count]+1; i <= max[count]+1; i++) {
		stamp[count+1] = i;
		memset(can, 0, sizeof(can));
		value = 0;
		dfs(0, count+1, 0);
		while(can[value+1])
			++value;
		max[count+1] = value;
		search(count+1);
	}
}

int main() {
	while(scanf("%d %d", &h, &k) != EOF) {
		if(h ==0 && k == 0)
			break;
		stamp[1] = 1;
		max[1] = h;
		Max = 0;
		search(1);
		for(int i = 1; i <= k; i++)
			printf("%3d", ans[i]);
		printf(" ->%3d\n", Max);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值