标签:一个 cout 多少 int lag eof const 注意 sig
给 \(n\) 个人安排座位,每个人手上有一个编号 \(a_i\)。从第一个人开始依次进场,每个人进场后,会从 \(a_i\) 往后找到第一个空着的座位就做,如果没找到则这个方案不合法。现在有 \(m\) 个人的座位已经确定(不同人的编号可以相同),求有多少种合法的安排方案。 \(T\leq 10, n \leq 300\)
考虑怎样的情况的是无解的,设 \(s_i\) 表示编号既定的 \(m\) 人中编号 \(\geq i\) 的人数,对于 \(s_i>n-i+1\) 显然是无解的
类似地,设 \(f[i][j]\) 为普通人中,编号 \(\geq i\) 的人中确定了 \(j\) 个人的编号的方案数,那么考虑在确定了 \(j-k\) 人编号的情况下,选择 \(k\) 人编号为 \(i\) 来进行转移
\[
f[i][j]=\sum_{k=0}^j f[i+1][j-k]\cdot C_j^k,\ \ 0\leq j\leq n-s_i-i+1
\]
答案就是 \(f[1][n-m]\)
注意无解一定要先判掉,不能等最后利用答案判。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 505;
int T,n,m,mod,p[N],q[N],f[N][N],c[N][N],s[N];
signed main() {
ios::sync_with_stdio(false);
cin>>T;
while(T--) {
memset(s,0,sizeof s);
memset(f,0,sizeof f);
memset(c,0,sizeof c);
cin>>n>>m>>mod;
c[0][0]=1;
for(int i=1;i<=n;i++) {
c[i][0]=1;
for(int j=1;j<=i;j++) {
c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
}
}
for(int i=1;i<=m;i++) {
cin>>p[i]>>q[i];
s[q[i]]++;
}
for(int i=n;i>=0;--i) s[i]+=s[i+1];
int flag=1;
for(int i=1;i<=n;i++) if(s[i]>n-i+1) flag=0;
if(flag==0) {
cout<<"NO"<<endl;
continue;
}
f[n+1][0]=1;
for(int i=n;i>=1;--i) {
for(int j=0;j<=n-s[i]-i+1;j++) {
for(int k=0;k<=j;k++) {
(f[i][j]+=f[i+1][j-k]*c[j][k])%=mod;
}
}
}
cout<<"YES "<<f[1][n-m]<<endl;
}
}
标签:一个 cout 多少 int lag eof const 注意 sig
原文地址:https://www.cnblogs.com/mollnn/p/12392042.html