条形码有多少种可能的方式出现限制约束

时间:2017-09-22 13:18:39

标签: algorithm dynamic-programming

这是我得到的平地机的作业之一。我已经在这个问题上苦苦挣扎了两天了。主题是关于动态编程,我不知道如何理解它。

详情如下。

条形码由不同排列的黑色和白色垂直线组成。为简单起见,我们使用字符串“0”和“1”来识别条形码,使得“0”表示黑线,而“1”表示白线。

条形码设计为对错误具有鲁棒性,因此必须遵循一些特定的规则:

1)条形码必须由 N

组成

2)相同颜色的连续线不能超过 M 。例如,当 M = 3 时,条形码“01100001”是非法的,因为它包含四条连续的白线。但是,1001100是合法的。

3)我们如下定义“变色”。两个时发生颜色变化 连续的线条有不同的颜色。例如,1001100有3种颜色 改变。条形码必须具有完全 K 颜色变化。

4)第一行总是黑线。

我们有兴趣知道关于给定的可能条形码的数量 值 N M K

输入 只有一行包含3个整数N,M和K,其中1 <= N,M <= 30且0 <= K <= 30

输出 输出必须只包含一行,给出可能的条形码数量。

例如

输入

4 3 1

输出

3

输入

5 2 2

输出

3

输入

7 9 4

输出

15

2 个答案:

答案 0 :(得分:1)

如果T(N,M,K)是输出,则有一个非常简单的递归关系:

T(N, M, K) = T(N - 1, M, K - 1) + T(N - 2, M, K - 1) + ... + T(N - M, M, K - 1)

有效条形码(N,M,K)始终是较小的有效条形码加上一种新颜色,此新颜色的大小可以是1到M之间的任何值。

由于这种关系,您可以为每个M创建一个N x K表,并使用动态编程解决O(N M K)中的问题。

这些规则应该足以初始化重复:

T(N, M, K) = 0 if (K >= N) and 1 if (K = N - 1)
T(N, M, K) = 0 if ((K+1) * M < N)

答案 1 :(得分:1)

在每个步骤(i条形码)我们有2个选项:选择白色还是黑色,然后根据更新你的状态(m和k)。

这里有一个带有评论的伪Java代码,不要犹豫,询问是否有不明确的内容:

    static int n,m,k,memo[][][][];
    static int dp(int i,int mm,int kk,int last) {
        if(mm > m || kk > k) return 0; // limitation constrains
        if(i==n) return kk==k?1:0; // if we build our barcode ( i == n ), we need to check color changing if it's ok return 1 else return 0
        if(memo[i][mm][kk][last] != -1) return memo[i][mm][kk][last]; // momoization
        int ans = 0;
        ans += dp(i+1,last==1?mm+1:1,kk+(last!=1?1:0),1); // choose black as a color of this one and update state ( mm, kk )
        ans += dp(i+1,last==0?mm+1:1,kk+(last!=0?1:0),0); // choose white as a color of this one and update state ( mm, kk )
        return memo[i][mm][kk][last] = ans;
    }

    public static void main (String[] args) throws java.lang.Exception {
        n = 4; m = 3; k = 1;
        memo = new int[n+1][m+1][k+1][2];
        for(int i=0;i<n;i++) for(int j=0;j<=m;j++) for(int l=0;l<=k;l++) Arrays.fill(memo[i][j][l], -1);
        System.out.print(dp(1,1,0,1));
    }