LuoguP2523 [HAOI2011]Problem c(概率DP)

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

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#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("
-----------
")
#define D_e(x) std::cout << (#x) << " : " <<x << "
"
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#define Pause() system("pause")
#include <ctime>
#define TIME() fprintf(stderr, "
TIME : %.3lfms
", 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<typename ATP> 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<typename ATP> inline ATP Min(ATP a, ATP b) {
	return a < b ? a : b;
}
template<typename ATP> 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
");
			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
", f[1][n - m]);
	}
	
	return 0;
}
原文地址:https://www.cnblogs.com/bingoyes/p/11693475.html