Description
to the n person to arrange the 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 beginning of a person, everyone in turn seated, I personally came to try to sit ai, if the AI is occupied, try to ai+1,ai+ 1 is also occupied, 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 a 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
10 3 8882
7 9 2 9 5 10
Sample Output
YES 4
NO
Idea: This is a better DP.
We can consider the situation without solution first:
We use the S[i] array, which represents the number of numbers greater than or equal to I. It is clear that this sequence is illegal when s[i]>n-i+1, and vice versa.
According to the above analysis, we can know whether the sequence is legal only with S.
Then we'll consider the legal situation without restrictions:
F[I][J] indicates that the element value is greater than or equal to I, there are J elements already determined (j<=n-i+1)
Then the DP equation is:
C[j][k] means that J elements select the number of combinations of I in K-positions.
consider the situation with limitations:
In fact, there are limitations of the situation is very simple, just need to change the limit J to J<=n-i+1-s[i], S[i] is the number of the previous request is greater than or equal to the number of I.
#include <iostream> #include <cstdio> #include <cstring>using namespace Std;long long t,n,p,q,m,pp,s[ 100001],d[100001],c[1001][1001],f[1001][1001];bool Ff;int Main () {cin>>t; for (int kk=1;kk<=t;kk++) {ff=true; cin>>n>>m>>pp; Memset (d,0,sizeof (d)); memset (F,0,sizeof (f)); Memset (s,0,sizeof (s)); for (int j=1;j<=m;j++) {scanf ("%d%d", &p,&q); d[q]++; } for (int j=n;j>=1;j--) {s[j]=s[j+1]+d[j]; if (s[j]>n-j+1) {ff=false; Break }} if (Ff==false) {printf ("no\n"); Continue } for (int i=0;i<=n;++i) {c[i][0]=c[i][i]=1; for (int j=1;j<=i;++j) {c[i][j]=c[i-1][j-1]+c[i-1][j]; if (c[i][j]>=pp) c[i][j]%=pp; } } f[n+1][0]=1; for (int i=1;i<=n;i++) f[n+1][i]=0; for (int i=n;i>=1;i--) for (int. j=0;j<=n-i-s[i]+1;j++) for (int k=0;k<=j;k++) F[i] [J]= (f[i][j]+ (F[i+1][j-k]*c[j][k]))%pp; printf ("YES"); printf ("%d\n", f[1][n-m]); }}?
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
"bzoj2302" "HAOI2011" "Problem C" "DP"