/VOI 22 Bài 2 - Đặc trưng đồ thị

<Problem>

https://oj.vnoi.info/problem/voi22_graph
              #define _CRT_SECURE_NO_WARNINGS

      #include <iostream>
      using namespace std;
      
      #define LIM 1000000007
      
      const int MAX = 2001;
      
      int main() {
      
        if (fopen("GRAPH.INP", "r")) {
          freopen("GRAPH.INP", "r", stdin);
          freopen("GRAPH.OUT", "w", stdout);
        }
      
        int n, b;
        cin >> n >> b;
      
        int* a = new int[n + 1];
      
        for (int i = 1; i <= n; i++) {
          cin >> a[i];
        }
      
        int f[MAX][MAX];
      
        for (int i = 0; i < MAX; i++) {
          for (int j = 0; j < MAX; j++) {
            f[i][j] = 0;
          }
        }
      
        // a[1] luon phai la 0 nen ta khoi tao f[1][0 -> b] = 1;
        for (int i = 0; i <= b; i++) {
          f[1][i] = 1;
        }
      
        for (int i = 2; i <= n; i++) {
          for (int gz = 0; gz <= n - i; gz++) {
            if (a[i] != -1) {
              if (a[i] < i && a[i] + gz <= b) {
                f[i][gz] = f[i - 1][gz + (a[i] > 0)];
              }
            }
            else {
              if (gz <= b) {
                int cnt = min(i - 1, b - gz); // f[i] thuoc doan [0,cnt];
                if (cnt >= 0) {
                  f[i][gz] = f[i - 1][gz];
                  f[i][gz] += (long long)cnt * f[i - 1][gz + 1] % LIM;
                  f[i][gz] = f[i][gz] % LIM;
                }
              }
            }
          }
        }
      
      /*for (int i = 1; i <= n; i++) {
        for (int gz = 0; gz <= n; gz++) {
          cout << f[i][gz] << " ";
        }
        cout << endl;
      }*/
      
      cout << f[n][0] % LIM << endl;
      
      return 0;
      }