SRM520 Div1 500

算数力が足りなくて、組合せが求められない。

以下のコードは、間違っています

#include <cmath>
#include <ctime>
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <map>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;

typedef long long ll;

ll dp[50][200001];
ll dp2[200001];

const ll mod = 1000000007;

class SRMIntermissionPhase {
public:
    int countWays( vector <int> points, vector <string> description ) {
        memset(dp, 0, sizeof(dp));
        memset(dp2, 0, sizeof(dp2));

        ll minp[50], maxp[50],cnty[50];
        for(int i=0; i<50; ++i) minp[i] = maxp[i] = cnty[i] = 0;
        const int n = description.size();

        for(int i=0; i<n; ++i) {
            for(int j=0; j<3; ++j)
                if(description[i][j]=='Y') {
                    maxp[i] += points[j];
                    minp[i] += 1;
                    cnty[i]++;
                }
        }

        for(int j=0; j<n; ++j)
            for(int i=minp[j]; i<=maxp[j]; ++i) {

                if(cnty[j] == 0) dp[j][0] = 1;
                if(cnty[j] == 1) dp[j][i] = 1;
                else if(cnty[j] == 2) {
                    // 誰かここと
                    if(description[j][0] == 'Y') {
                        dp[j][i] = min((ll)i-1,(ll)points[0]);
                    }else{
                        dp[j][i] = min((ll)i-1,(ll)points[1]);
                    }
                }else if(cnty[j] == 3) {
                    // ここを書いて!!!!!!!!!!!
                    ll tt = min((ll)points[0],(ll)i-2);
                    ll ts = max(i-points[1]-points[2],0);
                    dp[j][i] = tt*(i-1);
                    dp[j][i] -= tt*(tt+1)/2;
                    dp[j][i] -= ts*(i-1);
                    dp[j][i] += ts*(ts+1)/2;
                    dp[j][i] %= mod;
                }
            }

        ll tmp = 0;
        for(int j=maxp[0]; j>=minp[0]; --j) {
            tmp += dp[0][j];
            tmp %= mod;
            dp[0][j] = tmp;
        }

        for(int i=1; i<n; ++i) {
            for(int j=minp[i]; j<=maxp[i]; ++j) {
                dp[i][j] = dp[i-1][j+1] * dp[i][j];
                dp[i][j] %= mod;
            }

            tmp = 0;
            for(int j=maxp[i]; j>=minp[i]; --j) {
                tmp += dp[i][j];
                tmp %= mod;
                dp[i][j] = tmp;
            }
        }

        ll ans = dp[n-1][minp[n-1]];

        return ans;
    }
};