[atcoder 358] 【動態規劃】

fishcanfly發表於2024-06-15
  • dp[i][j] 表示前i個和為j的個數。那麼就有遞推式dp[i][j] += dp[i][j-x] * c(j,j-x); 其中x滿足從0到c[i],並且x滿足<=j

  • 組合數遞推公式c(n,k) = c(n,k-1) + c(n,k);


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

public class Main {
  public static void main(String[] args) throws IOException {
    int k = rd.nextInt();
    int[] c = new int[26];
    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < 26; i++) {
      c[i] = rd.nextInt();
      if (c[i] != 0) {
        list.add(c[i]);
      }
    }
    System.out.println(countEquations(c, k));
  }

  static long mod = 998244353;

  public static int countEquations(int[] c, int k) {
    countNonNegativeSolutions();
    int n = c.length;
    int[][] dp = new int[n + 1][k + 1];

    dp[0][0] = 1;

    for (int i = 1; i <= n; i++) {
      for (int j = 0; j <= k; j++) {
        for (int x = 0; x <= c[i - 1] && x <= j; x++) {
          if ( j > x ) {
            dp[i][j] += dp[i - 1][j - x] * dp2[j][j - x] % mod;
          } else {
            dp[i][j] +=  1L;
          }
          dp[i][j] %= mod;
        }
      }
    }

    int totalCount = 0;
    for (int j = 1; j <= k; j++) {
      totalCount += dp[n][j];
      totalCount %= mod;
    }

    return totalCount;
  }

  static long[][] dp2;

  public static void countNonNegativeSolutions() {
    // 初始化動態規劃陣列
    int MAX = 1001;
    dp2 = new long[MAX+1][MAX+1];

    // 設定初始狀態
    dp2[0][0] = 1;
    dp2[1][0] = 1;
    dp2[1][1] = 1;

    for (int n = 2; n <= MAX; n++) {
      dp2[n][0] = 1;
      for (int k = 1; k <= n; k++) {
        dp2[n][k] = dp2[n - 1][k - 1] + dp2[n - 1][k];
        dp2[n][k] %= mod;
      }
    }
  }

  static class rd {
    static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer tokenizer = new StringTokenizer("");

    // nextLine()讀取字串
    static String nextLine() throws IOException {
      return reader.readLine();
    }

    // next()讀取字串
    static String next() throws IOException {
      while (!tokenizer.hasMoreTokens()) { tokenizer = new StringTokenizer(reader.readLine()); }
      return tokenizer.nextToken();
    }

    // 讀取一個int型數值
    static int nextInt() throws IOException {
      return Integer.parseInt(next());
    }

    // 讀取一個double型數值
    static double nextDouble() throws IOException {
      return Double.parseDouble(next());
    }

    // 讀取一個long型數值
    static long nextLong() throws IOException {
      return Long.parseLong(next());
    }

    // 讀取一個BigInteger
    static BigInteger nextBigInteger() throws IOException {
      BigInteger d = new BigInteger(rd.nextLine());
      return d;
    }
  }
}

相關文章