/**
* 两个深搜! 下述的币值和面值是不一样的,币值是总的价值,面值是一张的价值。
* 一个是总的深搜,或者说就是枚举选取哪几种面值可以使得答案最大。
* 还一个是深搜来判断是否用当前已选择的面值在h(张数)的限制下能够获得当前币值。
* 其实,关键在于选择,比如,遇到一个面值,分为选择它或者不选择它,以此进行深搜,
* 判断的时候也是如此, Choose or not!
*
* 反省下:
* 惭愧啊! 学了那么久C,懂得思想,却一直忽略!
* 面向过程的C,把功能划分各模块各函数解决。。。
* 就说本题:其中的判断函数judge() 开始的时候,我是都在dfs一个函数都写
* 一大坨的看了恶心不说,还不能够实现,因为判断的时候也是需要深搜的。
* 看了人家的代码才理解,与其说看人家代码,还不如说直接copy了。。
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define MIN 0
using namespace std;
int maxMoney, ans[10], have[10];
int h, k, w;
bool judge(int tar, int th, int num, int th_end, int cur) {
if(cur == tar) return true;
if(th == th_end || num == h) return false;
if(judge(tar, th + 1, num, th_end, cur)) return true; //not choose
if(judge(tar, th, num + 1, th_end, cur + have[th])) return true; // choose
return false;
}
/** available 是已经能够得到的币值,th_end是用数组hava记录的已选取的面值。*/
void dfs(int available, int th_end) {
/** 递归的最后判断是否能够更新当前答案. */
if(available - 1> maxMoney) {
maxMoney = available - 1;
memcpy(ans, have, sizeof(have));
}
if(judge(available, 0, 0, th_end, 0))
dfs(available + 1, th_end); //不把当前面值 available 放入已取面值里
if(th_end < k) {
have[th_end++] = available;
dfs(available + 1, th_end); //把当前面值 available 放入已取面值里,此时th_end 已加一
th_end --;
have[th_end] = -1;
}
}
int main()
{
freopen("in.txt", "r", stdin);
while(scanf("%d%d", &h, &k), h && k) {
maxMoney = MIN;
dfs(0, 0);
memset(have, false, sizeof(have));
for(int i = 0; i < k; i ++) {
printf("%3d", ans[i]);
} printf(" ->");
printf("%3d\n", maxMoney);
}
return 0;
}