LuoguP2523 [HAOI2011]Problem c(概率DP)

傻逼概率\(DP\),熊大坐这,熊二坐这,两熊体积从右往左挤,挤到\(FFF\)没座位了就不合理了
否则就向左歇斯底里爬,每个\(FFF\)编号就组合一下,完闭

#include 
#include 
#include 
#include 
#include 
#define R(a,b,c) for(register int a = (b); a <= (c); ++a)
#define nR(a,b,c) for(register int a = (b); a >= (c); --a)
#define Fill(a,b) memset(a, b, sizeof(a))
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))

#define ON_DEBUGG

#ifdef ON_DEBUGG

#define D_e_Line printf("\n-----------\n")
#define D_e(x) std::cout << (#x) << " : " <
#define TIME() fprintf(stderr, "\nTIME : %.3lfms\n", clock() * 1000.0 / CLOCKS_PER_SEC)

#else

#define D_e_Line ;
#define D_e(x) ;
#define FileOpen() ;
#define FilSave ;
#define Pause() ;
#define TIME() ;

#endif

struct ios {
    template ios& operator >> (ATP &x) {
        x = 0; int f = 1; char c;
        for(c = getchar(); c < '0' || c > '9'; c = getchar()) if(c == '-') f = -1;
        while(c >= '0' && c <= '9') x = x * 10 + (c ^ '0'), c = getchar();
        x *= f;
        return *this;
    }
}io;

using namespace std;

template inline ATP Min(ATP a, ATP b) {
    return a < b ? a : b;
}
template inline ATP Max(ATP a, ATP b) {
    return a > b ? a : b;
}

const int N = 307;

int f[N][N], sum[N], c[N][N];

int main() {
    int Tasks, n, m, mod;
    io >> Tasks;
    while(Tasks--){
        Fill(sum, 0);
        Fill(f, 0);
        bool flag = false;
        io >> n >> m >> mod;
        R(i,1,m){
            int x;
            io >> x;
            io >> x;
            ++sum[x];
        }
        nR(i,n,1){
            sum[i] += sum[i + 1];
            if(sum[i] > n - i + 1){
                flag = true;
                break;
            }
        }
        if(flag == true){
            printf("NO\n");
            continue;
        }
        
        R(i,0,n) c[i][0] = 1;
        R(i,1,n){
            R(j,1,i){
                c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
            }
        }
        
        f[n + 1][0] = 1;
        nR(i,n,1){
            int maxn = n - i + 1 - sum[i];
            R(j,0,maxn){
                R(k,0,j){
                    f[i][j] = (f[i][j] + 1ll * f[i + 1][j - k] * c[j][k] % mod) % mod;
                }
            }
        }
        printf("YES %d\n", f[1][n - m]);
    }
    
    return 0;
}

你可能感兴趣的:(LuoguP2523 [HAOI2011]Problem c(概率DP))