UVA165

来源:互联网 发布:亲爱的你可知网络歌手 编辑:程序博客网 时间:2024/06/03 19:53

题意:h表示可以贴的邮票的数量,k表示能用的邮票的面值的数量,求所拥有的面值能连续组合而成到最大是多少,也就是连续邮资问题。

思路:DFS+回溯


#include<stdio.h>#include<stdlib.h>#include<math.h>#include<algorithm>#include<string.h>using namespace std;int h, k, d;int a[11], b[11], vis[200];void judge(int n, int m, int sum){if (m == h){vis[sum] = 1;return;}vis[sum] = 1;for(int i = 0;i <= n; i++)judge(n, m + 1, sum + a[i]);}//标记目前已有面值所组合而成的和void dfs(int cur, int num){ //依次往下推导下一个面值if (cur > k){if (num - 1 > d){d = num -1;memcpy(b, a, sizeof(a));}return;}for(int i = a[cur - 1] + 1;i <= num; i++){a[cur] = i;memset(vis, 0, sizeof(vis));judge(cur, 0, 0);int j = a[cur - 1];//从上一层的面值和的数开始判断,知道遇到第一个么标记过的跳出while (vis[++j]);dfs(cur + 1, j);}}int main(){while (scanf("%d %d", &h, &k) && h && k){a[0] = 0;a[1] = 1;d = 0;dfs(2, h + 1);for(int i = 1;i <= k; i++)printf("%3d", b[i]);printf(" ->");printf("%3d\n", d);}return 0;}