用长度为s和t的长棍填充长度为L的孔的方法

时间:2015-06-12 16:00:45

标签: permutation dynamic-programming

我需要帮助来修改我为编程挑战提出的解决方案。问题陈述如下:

马达加斯加的斑马马丁(电影)希望填补在海滩边缘建造的小屋地板上留下的洞。洞的长度为L,马丁有许多木头,有些长度为s,有些长度为t。由于马丁非常分心,他想通过随意放置木块来了解孔的填充方式。

输入规范
唯一的输入行包含用空格分隔的三个整数L,s和t(1 <= L,s,t <= 10 ^ 6,s!= t)。

输出规格
一条线以不同的方式填充孔模数10 ^ 9 + 7(1000000007)。

示例输入
6 2 3

示例输出
2

我提交的解决方案使用此功能计算:

#include <iostream>
#include <vector>

using namespace std;

int ** create(int n, int m) {
  int ** a = new int*[
  for (int i = 0; i < n; i++) {
    a[i] = new int[m]; 
    a[i][0] = 1; // I assumed there is one way to fill a hole of length zero
  }
  return a;
}

int count(vector<int>  stick, int n, int m) { // Counts ways to fill the hole
  int ** fill = create(n + 1, m + 1);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      if (j < stick[i - 1])
        fill[i][j] = fill[i - 1][j] % 1000000007;
      else
        fill[i][j] = (fill[i - 1][j] + fill[i][j - stick[i - 1]]) %   1000000007;
  return fill[n][m];
}

int main() {
  int l, a, b;
  cin >> l >> a >> b;
  vector<int> stick{a, b};
  cout << count(stick, stick.size(), l) << endl;
  return 0;
}

问题在于,这只计算可以完全填补空洞的不同集合,例如:

假设我们有一个长度为L = 6的洞和长度为s = 1且t = 2的长度,我的函数返回4.这是我的函数计算的四个集合:

{1, 1, 1, 1, 1, 1}
{1, 1, 1, 1, 2}
{1, 1, 2, 2}
{2, 2, 2}

但它需要的是这些集合的所有排列,因此这应该返回13,即:

{1, 1, 1, 1, 1, 1}
{1, 1, 1, 1, 2}
{1, 1, 1, 2, 1}
{1, 1, 2, 1, 1}
{1, 2, 1, 1, 1}
{2, 1, 1, 1, 1}
{1, 1, 2, 2}
{1, 2, 1, 2}
{2, 1, 1, 2}
{1, 2, 2, 1}
{2, 1, 2, 1}
{2, 2, 1, 1}
{2, 2, 2}

如何修改我的功能以计算所有排列?是否有任何材料可以帮助我理解如何为这类问题构建动态编程解决方案?

1 个答案:

答案 0 :(得分:3)

d[i] - 填补长度空洞的方法数量

然后d[i] = d[i-s] + d[i-t]

d[0] = 1
显然

d[i < 0] = 0