题意
给出一个长度为n的01序列,有m次操作,第i次可以把区间[li,ri]中的元素任意排列。问该序列可以通过操作得到多少种不同的序列。
n,m<=3000,保证li单调不降。
分析
先把操作区间变成左端点和右端点均单调递增,然后设f[i,j]表示前i个位置的元素已经确定,且前i个位置中恰好有j个1的摆放方案。
在一次操作[l,r]时,设下一个区间的左端点为nx,我们考虑由f[l-1,j]转移给f[nx-1,k]。因为当我们把[l,nx-1]中的元素固定后,由于左端点递增,所以这部分的元素已经不能再改变。
转移的时候可以枚举在[l,nx-1]中放多少个1,然后乘上一个组合数即可。
这样做看似是O(n^3)的,但分析一下不难发现复杂度其实是O(n^2)。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std