hdu 5151 Sit sit sit(区间dp+排列组合)

题目链接: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 }
View Code

 

posted @ 2017-02-21 16:05  bin_gege  阅读(137)  评论(0编辑  收藏  举报