Gym - 101128E Wooden Signs DP

题目大意:

一共n块木板,前两个数给出最底下木块的两个端点,后面n-1个数给出第i层的一个固定端点,问你木块的所有放置情况。

分析:

状态:

d[i][j]表示第i个木块,第i-1块木板的未固定端点为j的所有方案数

状态转移:

         如果a[i]<=min(j,a[i-1),也就是说固定的那一点在i-1块木板的两个端点的左侧,那么只能有一种情况。d[i][r]=(d[i][r]+d[i-1][j])%mod;

         同理,如果a[i]>= max(j,a[i-1)。d[i][l]=(d[i][l]+d[i-1][j])%mod;

         如果在中间,那么以上两种情况都要算上

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll mod=2147483647;
const int maxn=2000+5;
int n,a[maxn];
ll d[maxn][maxn];


int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=0; i<=n; i++)
            scanf("%d",&a[i]);
        memset(d,0,sizeof(d));
        d[1][a[0]]=1;
        for(int i=2; i<=n; i++)
        {
            for(int j=1; j<=n+1; j++)
            {
                int l=min(j,a[i-1]);
                int r=max(j,a[i-1]);
                if(a[i]<=l)
                    d[i][r]=(d[i][r]+d[i-1][j])%mod;
                else if(a[i]>=r)
                    d[i][l]=(d[i][l]+d[i-1][j])%mod;
                else
                {
                    d[i][r]=(d[i][r]+d[i-1][j])%mod;
                    d[i][l]=(d[i][l]+d[i-1][j])%mod;
                }
            }
        }
        ll ans=0;
        for(int j=1; j<=n+1; j++)
            ans=(ans+d[n][j])%mod;
        printf("%I64d\n",ans);
    }
    return 0;
}

 

posted @ 2017-05-28 22:07  Pacify  阅读(232)  评论(0编辑  收藏  举报