【cf268D】Wall Bars

2015.03.21 15:52 Sat | 3次阅读 | 旧日oi | 固定链接 | 源码

Manao is working for a construction company. Recently, an order came to build wall bars in a children's park. Manao was commissioned to develop a plan of construction, which will enable the company to save the most money.
After reviewing the formal specifications for the wall bars, Manao discovered a number of controversial requirements and decided to treat them to the company's advantage. His resulting design can be described as follows:

  • Let's introduce some unit of length. The construction center is a pole of height n
  • At heights 1, 2, ..., n exactly one horizontal bar sticks out from the pole. Each bar sticks in one of four pre-fixed directions
  • A child can move from one bar to another if the distance between them does not exceed h and they stick in the same direction. If a child is on the ground, he can climb onto any of the bars at height between 1 and h. In Manao's construction a child should be able to reach at least one of the bars at heights n - h + 1, n - h + 2, ..., n if he begins at the ground.The figure to the left shows what a common set of wall bars looks like. The figure to the right shows Manao's construction Manao is wondering how many distinct construction designs that satisfy his requirements exist. As this number can be rather large, print the remainder after dividing it by 1000000009 (109 + 9). Two designs are considered distinct if there is such height i, that the bars on the height i in these designs don't stick out in the same direction. Input A single line contains two space-separated integers, n and h (1 ≤ n ≤ 1000, 1 ≤ h ≤ min(n, 30)). Output In a single line print the remainder after dividing the number of designs by 1000000009 (109 + 9). Sample test(s) input 5 1 output 4 input 4 2 output 148 input 4 3 output 256 input 5 2 output 376 题解 一道不错的dp题,用F[curn][st][x][y][z]表示第curn层,上一层摆放木棍的位置能否从底端到达,以及另外3个方向离当前层的距离 转移的时候分别对另外三个方向进行修改,转移时间复杂度o1,curn可用滚动数组,空间复杂度没有问题 ##我的程序
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<bitset>
#include<stack>
#include<ctime>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#define ull unsigned long long
#define mod 1000000009
#define inf 0x3f3f3f3f
#define ll long long
#define maxn 100010
#define add(x,y) x=(x+y)%mod
using namespace std;
int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,h,s,now;
int f[2][2][31][31][31];
int main()
{
    freopen("climb.in","r",stdin);
    freopen("climb.out","w",stdout);
    n=read();h=read();
    f[1][1][1][1][1]=4;
    for(s=0,now=2;now<=n;now++,s^=1)
    {
        for(int i=0;i<=h;i++)
        {
            for(int j=0;j<=h;j++)
            {
                for(int k=0;k<=h;k++)
                {
                    for(int opt=0;opt<2;opt++)
                    {
                        int temp=f[s^1][opt][i][j][k];f[s^1][opt][i][j][k]=0;
                        int I=min(i+1,h),J=min(j+1,h),K=min(k+1,h);
                        int P=opt?1:h;
                        add(f[s][opt][I][J][K],temp);
                        add(f[s][i<h][P][J][K],temp);
                        add(f[s][j<h][I][P][K],temp);
                        add(f[s][k<h][I][J][P],temp);
                    }
                }
            }
        }
    }
    ll ans=0;
    for(int i=0;i<=h;i++)
    for(int j=0;j<=h;j++)
    for(int k=0;k<=h;k++)
    {
        add(ans,f[s^1][1][i][j][k]);
        if(i<h||j<h||k<h)
        add(ans,f[s^1][0][i][j][k]);
    }
    cout<<ans;
}```