寻找最优子结构

Finding optimal substructure

本文关键字:结构 寻找      更新时间:2023-10-16

我正在寻找一些关于动态编程问题的指针。我找不到任何关于如何解决这类问题的相关信息。

问题

 A number is called a special number if it doesn't contain 3 consecutive 
 zeroes. i have to calculate the number of positive integers of exactly d digits 
 that are special answer should be modulo 1000000007(just for overflow in c++).

问题可以很容易地通过排列和组合来解决,但我希望它与动态规划。我无法找到它的最佳子结构或自下而上的方法。

f(d,x)为最后一个x数字为零的最高有效d数字的数量,其中0≤x≤2.对于d>1、我们有复发:

f(d,0)=(f(d-1,0)+f(d-1,1)+ff(d,1)=f(d-1,0)//ff(d,2)=f(d-1,1)//f(d、2)来自d-1数字模式,其中一个尾随零后加一个零

对于d=1,我们有f(1,0) = 9, f(1,1) = 0, f(1,2) = 0

原来问题的最终答案是f(d,0) + f(d,1) + f(d,2)

这里有一个简单的演示C程序:

#include <cstdio>
const int MOD = 1000000007;
long long f[128][3];
int main() {
  int n;
  scanf("%d",&n);
  f[1][0] = 9;
  for (int i = 2 ; i <= n ; ++i) {
    f[i][0] = (f[i-1][0] + f[i-1][1] + f[i-1][2]) * 9 % MOD;
    f[i][1] = f[i-1][0];
    f[i][2] = f[i-1][1];
  }
  printf("%lldn", (f[n][0] + f[n][1] + f[n][2]) % MOD);
  return 0;
}

注意:我还没有彻底测试我的逻辑,所以请指出我可能错在哪里。

问题的复发可能是

f(d)=f(d/2)*f(d-d/2)-( f(d/2-1)*f(d-d/2-2) + f(d/2-2)*f(d-d/2-1) )f(0)=1;f(1)=10;f(2)=100;f(3)=999;

这里,f(i)是考虑到"0"可以作为第一个数字出现,可以形成的特殊数字的总数。因此,"d"数字的实际答案是9*f(d-1)

您可以很容易地将递归解决方案记忆起来,以制作DP解决方案。

我还没有试过这个解决方案的有效性,所以它可能是错误的。这是我的逻辑:

对于f(d),将数字划分为d/2(d-d/2)位数,加上f(d)*f(d-d/2)的乘积。现在,要删除可能在我们创建的分区中出现的无效情况,请从答案中减去f(d/2-1)*f(d-d/2-2) + f(d/2-2)*f(d-d/2-1)(假设在我们创建了分区中出现三个零)。用纸和笔试试,你就会得到它。