有一天,Dragonfly收到了n份巧克力。在决定将巧克力分发给他的朋友之后,他提出了以下规则:
首先,根据友谊的亲密关系,他会将他的朋友从1分到1分?
第二,如果排名第一的朋友获得x巧克力(F[i]=x
),那么x+1
的朋友应该获得不少于x巧克力且不超过x+k
巧克力(所以x <= F[i+1] <= x +k
),其中k
是正数。
第一位的朋友不应该超过k个巧克力(所以F[1] <= k
)
有些朋友可能会得到零巧克力。
如果可能的话,Dragonfly应该没有巧克力。他有牙痛,不应该吃糖果。
虽然不精通数学,但Dragonfly非常想知道所有巧克力的分布方式。所以他正在寻求你的帮助
输入文件由一系列输入行组成,每行输入行定义一个案例。每个案例的输入是一行三个正整数:
N (1 <= n <= 500), m (1 <= m <= 100), k (1 <= k <= 100).
输入文件将由0 0 0
终止。
对于每种情况输出所有巧克力可以在一条线上分配的方式。
示例输入:
1 1 1
4 2 2
5 3 2
0 0 0
输出:
1
2
3
原始页面:http://acm.whu.edu.cn/learn/problem/detail?problem_id=1031
我尝试了递归方法,但超出了时间限制。然后我尝试用队列替换递归但超过了内存限制。这是关于动态编程的问题吗?谁能给我一个提示?
答案 0 :(得分:1)
你试过在你的恢复方法中添加一些修剪吗?即。如果剩下的糖果由于这种限制而无法分发给其他朋友,你可以就此停止。
你也可以使用DP方法。让f [i] [j] [k]表示为第一个朋友分发的可能方式的数量,第i个朋友有j个糖果,还有k个剩余的糖果。
boundary: f[0][0][n]=1;
u can use forward recurrence:
f[i+1][j+l][k-(j+l)]+=f[i][j][k]; 0<=l<=K (K here is what in your input)
the final answer is sum(0<=i<=n)(f[m][i][0])