题目链接:hdu 5151 Sit sit sit
题意:
一共有并排N个椅子, N个学生依次去坐,同时满足3个条件就不能坐下去:
1,该椅子不在最左,不在最右。
2,该椅子左右都有人坐了。
3,左右的椅子不同颜色。
求最后N个人都能坐下去,有多少不同的情况.
题解:
考虑区间dp,dp[i][j] = sum(dp[i][k-1] * dp[k+1][j] * c[j - i][k - i])其中满足(v[k-1]==v[k+1])
表示i到j区间最后来坐k位置,乘组合是因为合并这两段区间的时候,j-i个人中选择k-i个人去坐左区间的位置,剩下的就坐右区间的位置。
1 #include<bits/stdc++.h> 2 #define mst(a,b) memset(a,b,sizeof(a)) 3 #define F(i,a,b) for(int i=a;i<=b;++i) 4 using namespace std; 5 typedef long long ll; 6 const int P=1e9+7,N=107; 7 8 ll c[N][N],dp[N][N]; 9 int n,v[N]; 10 11 void Init() 12 { 13 for(int i=0;i<=100;i++) 14 { 15 c[i][0]=c[i][i]=1; 16 for(int j=1;j<i;j++)c[i][j]=(c[i-1][j]+c[i-1][j-1])%P; 17 } 18 } 19 20 int main() 21 { 22 Init(); 23 while(~scanf("%d",&n)) 24 { 25 F(i,1,n)scanf("%d",v+i); 26 mst(dp,0); 27 F(i,1,n)dp[i][i]=1; 28 F(l,2,n)F(i,1,n-l+1) 29 { 30 int j=i+l-1; 31 dp[i][j]=(dp[i+1][j]+dp[i][j-1])%P; 32 F(k,i+1,j-1)if(v[k-1]==v[k+1]) 33 { 34 dp[i][j]=(dp[i][j]+dp[i][k-1]*dp[k+1][j]%P*c[j-i][k-i])%P; 35 } 36 } 37 printf("%lld\n",dp[1][n]); 38 } 39 return 0; 40 }