2302: [Haoi2011]problem C Time limit:30 Sec Memory limit:256 MB
submit:937 solved:509
[Submit] [Status] [Discuss] Description to the n person to arrange a seat, first give each person a 1~n number, set the first person's number is AI (different person's number can be the same), and then from the first person to start, everyone in turn seated, I personally came to try to sit after the AI, if the AI was occupied, If you try to ai+1,ai+1, you try to ai+2, ..., if you try to get to Nth, the arrangement is illegal. However there are m personal numbers already identified (they may have bribed your boss ...), you can only arrange the number of the remainder, and ask how many legal arrangements. Because the answer can be large, simply output the remainder after dividing by M. Input
The first line is an integer t, which indicates the number of data groups
For each set of data, the first row has three integers representing N, m, m
If M is not 0, then the next line has m-pairs of integers, p1, q1,p2, Q2,..., pm, QM, where I pairs the integer pi, qi, the number of pi individuals must be qi Output
For each set of data output row, if there is a solution output Yes, followed by an integer to indicate the number of scenarios mod M, note that there is only one space between yes and no, otherwise output no Sample Input 2 4 3 10
1 2 2 1 3 1 Ten 3 8882 7 9 2 9 5 Sample Output YES 4 NO
DP[I][J] Indicates the total number of <=i with a J person
DP[I][J] =∑ (Dp[i-1][j-k]*c (N-m+sum[i]-j+k-loc[i], k-loc[i]) k∈[loc[i], j-i+1])
Where Loc[i] indicates that there is a loc[i] personal number is i,sum[i] is the prefix of loc[i] and
#include <stdio.h>
#include <string.h>
#define LL long long
int c[305][305], loc[305], sum[305 ];
LL dp[305][305];
int main (void)
{
int T, n, M, I, J, K, mod, X;
scanf ("%d", &t);
while (t--)
{
scanf ("%d%d%d", &n, &m, &mod);
for (i=0;i<=300;i++)
{
c[i][0] = 1;
for (j=1;j<=i;j++)
c[i][j] = (c[i-1][j-1]+c[i-1][j])%mod;
}
memset (Loc, 0, sizeof (LOC));
for (i=1;i<=m;i++)
{
scanf ("%*d%d", &x);
LOC[X] + = 1;
}
for (i=1;i<=n;i++)
{
Sum[i] = sum[i-1]+loc[i];
if (m-sum[i]>n-i)
{
printf ("no\n");
break;
}
}
if (i<=n)
continue;
memset (DP, 0, sizeof (DP));
Dp[0][0] = 1;
for (i=1;i<=n;i++)
{for
(j=i;j<=n-(M-sum[i]); j + +)
{for
(k=loc[i];k<=j-(i-1); k++)
Dp[i][j] = (dp[i][j]+dp[i-1][j-k]*c[n-(M-sum[i])-(J-K)-loc[i]][k-loc[i]])%mod;
}
}
printf ("YES%lld\n", Dp[n][n]);
}
return 0;
}