hdu5151 Sit sit sit 区间DP

来源:互联网 发布:htpc 软件 编辑:程序博客网 时间:2024/06/05 05:10

点击打开链接

题意:一共有并排N个椅子, N个学生依次去坐,同时满足3个条件就不能坐下去:1,该椅子不在最左,不在最右,2,该椅子左右都有人坐了,3,左右的椅子不同颜色
求最后N个人都能坐下去,有多少不同的情况.

分析:不好想啊,dp[i][j]表示i-j坐满的情况总数,dp[i][j]=sum(dp[i][k-1]*dp[k+1][j]*C[j-i][k-i]),k为i-j最后一个被坐的位置。

乘以组合数的原因是在j-i个人中决定坐前一个区间的人(选完之后,他们是有序的)。

#include<iostream>#include<string>#include<cstring>#include<cstdio>#include<cmath>#include<iomanip>#include<map>#include<algorithm>#include<queue>#include<set>#define inf 10000000#define pi acos(-1.0)#define eps 1e-8#define seed 131using namespace std;typedef pair<int,int> pii;typedef unsigned long long ULL;typedef long long LL;const int maxn=100005;const LL mod=1000000007;int n;LL dp[105][105];LL C[105][105];int p[105];int main(){    for(int i=0;i<=105;i++)    {        C[i][0]=1;        C[i][i]=1;        for(int j=1;j<i;j++)            C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;    }    while(~scanf("%d",&n))    {        for(int i=1;i<=n;i++)            scanf("%d",&p[i]);        for(int i=1;i<=n;i++)        {            dp[i][i]=1;            dp[i][i-1]=1;            dp[i+1][i]=1;        }        for(int l=2;l<=n;l++)        {            for(int i=1;i<=n;i++)            {                int j=i+l-1;                if(j>n)                    break;                dp[i][j]=0;                for(int k=i;k<=j;k++)                {                    if(k==i||k==j||p[k-1]==p[k+1])                    {                        dp[i][j]=(dp[i][j]+(dp[i][k-1]*dp[k+1][j])%mod*C[j-i][k-i]%mod)%mod;                    }                }            }        }        cout<<dp[1][n]<<endl;    }    return 0;}


0 0
原创粉丝点击