uva 165(暴力求解)

题意:输入h,k,h是邮票需要的数量, k是面额不同的邮票的种数,要求输出,如果k种邮票任意组合成h张所能取得的一系列和,是从1开始连续且长度最长的,就将这种情况输出出来,并且邮票的和能达到的最大连续值也输出出来。

题解:用两个数组den[N],表示当前有哪些不同面面额的邮票,den[0]一定是1,不然无法从1连续,另一个数组是val[N],表示当前这种面额的邮票所能达到的最大连续面额,

因此val[0] 是h*1,然后进行递归来更新每种面额val值,然后每种面额的邮票的选取也是有范围的,假设当前要找cur这个位置的面额,是从den[cur - 1] + 1 到 val[cur - 1] + 1,如果超过了这个范围就会导致无论怎么取值都不会连续,然后接着用递归从这个范围内找到每个面额和最大连续值。

#include <stdio.h>
#include <string.h>
const int N = 10;
const int MAX = 200;
int h, k, den[N], pos[MAX], val[N], ans, res[N];

void dfs(int num, int now, int count) {
	if (num >= h) {
        pos[count] = 1;
        return;
	}
	pos[count] = 1;
	for (int i = 0; i <= now; i++)
        dfs(num + 1, now, count + den[i]);
}

void solve(int cur) {
    if (cur >= k) {
        if (val[cur - 1] > ans) {
            ans = val[cur - 1];
            memcpy(res, den, sizeof(den));
        }
        return;
    }
	for (int i = den[cur - 1] + 1; i <= val[cur - 1] + 1; i++) {
		memset(pos, 0, sizeof(pos));
		den[cur] = i;
		dfs(0, cur, 0);
		int num = 0, n = 1;
		while (pos[n++])
			num++;
		val[cur] = num;
		solve(cur + 1);
	}
}

int main() {
	int i, j;
	while (scanf("%d%d", &h, &k) && (h || k)) {
		ans = 0;
		den[0] = 1;
		val[0] = h;
		solve(1);
		for (int i = 0; i < k; i++)
		printf("%3d", res[i]);
		printf(" ->%3d\n", ans);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值