CF367E 翻

my

[[interval DP]]
link

Pro

Calculate the number of states(interval sequence) meet following conditions:

  • Each interval does not belong to any other interval.

  • Exist one \(l_i=x\) .

\(n, m, x (1 ≤ n·m ≤ 100000, 1 ≤ x ≤ m)\) — the number of segments in the sequence, the constraints on the numbers in segments and Sereja's favourite number.

Sol

\(n\) must <= \(m\).

State as \(dp_{i,l,r}\) is too big.

How can we represent the states more properly?
Since the intervals don't belong to each other, the order of start and end position of intervals is fixed.

see this picture 1

\(dp_{p,i,j}\) has four transfer equations.

whether start a new interval, and whether finish the farthest interval.

After a seris of optimization, the code is following

Reverse the traversal direction, so we can remove the p dimention.

We must open a new interval when \(p=x\), so the next states can only be added twice.

#include<bits/stdc++.h>
using namespace std;
const int mod=1000000007,N=333;
int n,m,x,o,a,f[N][N];
inline void add(int &o){o+=a;if(o>=mod)o-=mod;}
int main(){
	int p,i,j;
	scanf("%d%d%d",&n,&m,&x);
	if(n>m)return puts("0"),0;
	for(p=f[0][0]=1;p<=m;p++){
		for(i=min(p,n);i>=0;i--){
			for(j=i;j>=0;j--){
				if(a=f[i][j]){
					add(f[i+1][j]);
					add(f[i+1][j+1]);
					if(p==x)f[i][j]=0;
					else if(j<i)add(f[i][j+1]);
				}
			}
		}
	}
	long long ans=f[n][n];
	for(int i=1;i<=n;i++){
		ans=ans*i%mod;
	}
	printf("%lld",ans);
}

Complexity: \(O(m*n^2)\), at most 3e7.

posted @ 2022-12-11 11:48  -WD-  阅读(63)  评论(0)    收藏  举报