AtCoder Regular Contest 065 Shuffling 动态规划
2018-02-27 09:39
399 查看
题意
给出一个长度为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; typedef long long LL; const int N=3005; const int MOD=1000000007; int n,m,c ,a ,f ; struct data{int l,r;}op ; char str ; bool cmp(data a,data b) { return a.l<b.l||a.l==b.l&&a.r<b.r; } void mod(int &x) { x-=x>=MOD?MOD:0; } void prepare() { c[0][0]=1; for (int i=1;i<=n;i++) { c[i][0]=1; for (int j=1;j<=i;j++) mod(c[i][j]=c[i-1][j]+c[i-1][j-1]); } } int main() { scanf("%d%d",&n,&m); prepare(); scanf("%s",str+1); for (int i=1;i<=n;i++) a[i]=a[i-1]+str[i]-'0'; for (int i=1;i<=m;i++) scanf("%d%d",&op[i].l,&op[i].r); sort(op+1,op+m+1,cmp); int tmp=m,mx=0; for (int i=1;i<=m;i++) if (op[i].l==op[i+1].l||op[i].r<=mx) tmp--,op[i].l=n+1; else mx=max(mx,op[i].r); sort(op+1,op+m+1,cmp); m=tmp; f[op[1].l-1][a[op[1].l-1]]=1; op[m+1].l=n+1; for (int i=1;i<=m;i++) { int l=op[i].l,r=op[i].r,nx=op[i+1].l; for (int j=0;j<l;j++) { if (!f[l-1][j]) continue; int s=a[r]-j,p=max(0,s-(r-nx+1)),q=min(s,nx-l); if (nx>r) {mod(f[nx-1][a[nx-1]]+=(LL)f[l-1][j]*c[r-l+1][s]%MOD);continue;} if (p>q) continue; for (int k=p;k<=q;k++) mod(f[nx-1][j+k]+=(LL)f[l-1][j]*c[nx-l][k]%MOD); } } printf("%d",f [a ]); return 0; }
相关文章推荐
- AtCoder Regular Contest 081 F - Flip and Rectangles 动态规划
- AtCoder Regular Contest 068 F - Solitaire 动态规划
- AtCoder Regular Contest 071 F - Infinite Sequence 动态规划
- AtCoder Regular Contest 074 E - RGB Sequence 动态规划
- AtCoder Regular Contest 066 E - Addition and Subtraction Hard 动态规划
- AtCoder Regular Contest 088
- AtCoder Regular Contest 077 E - guruguru
- AtCoder Regular Contest 073 F - Many Moves 线段树优化dp
- [AtCoder Regular Contest 064] F: Rotated Palindrome (arc064F)
- AtCoder Regular Contest D - Remainder Reminder 取余问题
- AtCoder Regular Contest 092-C
- 【搜索】[AtCoder Regular Contest 092 F]Two Faced Edges
- AtCoder Regular Contest 093 D - Grid Components
- AtCoder Regular Contest 078-C - Splitting Pile
- AtCoder Regular Contest 082
- AtCoder Regular Contest 082 E
- 【Atcoder Regular Contest 085F】 NRE
- AtCoder Regular Contest 086 E - Smuggling Marbles(树形迭屁)
- Atcoder regular Contest 073(D - Simple Knapsack)
- AtCoder Regular Contest 090 D - People on a Line