繁体   English   中英

使用范围 1 到 k 查找总和值的方法数

[英]Find the number of ways to find the total sum value using the range 1 to k

给定一个总数作为总数,我需要计算表示 1 和 k(含)之间总数的方法数。

例如:total=5 and k=3 即(1 到 3),没有。 的方式= 5,不同的方式是:

[1+1+1+1+1]
[1+1+1+2]
[1+2+2]
[1+1+3]
[2+3]

我的代码产生 6 而不是 5。谁能帮我解决这个问题:

public static int ways(int total, int k) {
    int C[][] = new int[n + 1][k + 1];
    int i, j;
    for (i = 0; i <= n; i++) {
        for (j = 0; j <= Math.min(k, i); j++) {
            if (j == 0 || j == i) {
                C[i][j] = 1;
            } else {
                C[i][j] = C[i - 1][j - 1] + C[i - 1][j - 1];
            }
        }
    }
    return C[n][k];
}

您可以使用递归解决它,如下所示:

public class IntegerPartition {
    static int count=0;
    public static void partition(int total, int k) {
        partition(total, k, "");
    }
    public static void partition(int n, int max, String prefix) {
        if (n == 0) {
            System.out.println(prefix);
            count++;
            return;
        }
        for (int i = Math.min(max, n); i >= 1; i--) {           
            partition(n - i, i, prefix + " " + i);
        }
    }

    public static void main(String[] args) {
        partition(5,3);
        System.out.println("Count: "+count);
    }
}

Output:

 3 2
 3 1 1
 2 2 1
 2 1 1 1
 1 1 1 1 1
Count: 5

如果您对仅查找计数感兴趣,可以进一步缩短代码,如下所示:

public class IntegerPartition {
    static int count=0;
    public static void partition(int n, int max) {
        if (n == 0) {
            count++;
            return;
        }
        for (int i = Math.min(max, n); i >= 1; i--) {           
            partition(n - i, i);
        }
    }
    public static void main(String[] args) {
        partition(5,3);
        System.out.println("Count: "+count);
    }
}

Output:

Count: 5

这是我的答案:


private static int numberOfWaysForSum(int n, int k) {
  int[][] a = new int[k + 1][n + 1];
  for (int i = 1; i <= n; i++) {
    a[1][i] = 1;

  }
  for (int i = 1; i <= k; i++) {
    a[i][0] = 1;
  }
  for (int i = 2; i <= k; i++) {
    for (int j = 1; j <= n; j++) {
      if (j >= i) {
        a[i][j] = a[i][j - i] + a[i - 1][j];

      } else {
        a[i][j] = a[i - 1][j];
      }

    }
  }
  return a[k][n];
}

这类似于 GeekForGeeks 解决的动态规划问题。 这是链接: https://www.geeksforgeeks.org/count-ofdifferent-ways-express-n-sum-1-3-4/

注意模式。 如果要将数字 N 表示为范围 (1,K) 内的整数之和。 以 N = 5 和 K = 3 为例。可能的组合有:

  1. 1+1+3 = 1+1+(1+1+1)
  2. 1+3+1 = 1+(1+1+1)+1
  3. 3+1+1 = (1+1+1)+1+1
  4. 1+2+2 = 1+(1+1)+1
  5. 2+1+2 =...
  6. 2+2+1 =... 或者简单来说,将 N 转换为 1 的总和。

N = 1 + 1 + 1 +... + 1。注意等式右侧它们之间的 (N-1) 个“+”号。 所以对于 N 个 1,我们需要 N-1 个“+”。 此外,等式左侧有 (K-1) 个“+”号。 所以我们需要的没有。 方法只是(N-1)C(K-1)或(N-1,K-1)的二项式系数。 这可以通过递归或动态规划来解决。

这是我在 Python 中的答案,这是基于 0-1 背包问题。

#total = int(input())
#k = int(input())
total = 8
k = 2
## making an array of size [k+1][total+1]
arr = [[0 for y in range(total+1)]for x in range(k+1)]

for i in range(total+1):
  arr[0][i] = 0
  arr[1][i] = 1

for i in range(k+1):
  arr[i][0] = 0
#print(arr)
for row in range(2,k+1):
  for col in range(1,total+1):

    if col < row:
      arr[row][col] = arr[row-1][col]
    elif col == row:
      arr[row][col] = arr[row-1][col] + 1
    else:
      arr[row][col] = arr[row-1][col]  +  arr[row][col-row]

print(arr[k][total])

这是我使用 DP 的 java 解决方案

private static int ways(int total, int k) {
    int[][] t = new int[k + 1][total + 1];
    for (int i = 1; i <= k; i++) {
        for (int j = 1; j <= total; j++) {
            if (j < i)
                t[i][j] = t[i - 1][j];
            else if (i == j)
                t[i][j] = 1 + t[i - 1][j];
            else
                t[i][j] = t[i - 1][j] + t[i][j - i];

        }
    }
    return t[k][total];

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM