HDU 2861 (DP+打表)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2861

题目大意:n个位置,m个人,分成k段,统计分法。S(n)=nk=0CknFibonacci(k)

解题思路

感觉是无聊YY出的DP,数据目测都卡了几W组。如果不一次打完,那么直接T。$DP[i][j][k][0|1]$

用$DP[i][j][k][0|1]$表示,$i$位置,已经安排了$j$个人,有$k$段,且$i$位置不放人/放人。

边界

$DP[0][0][0][0]=DP[0][0][0][1]=1$

转移方程

$DP[i][j][k][0]=DP[i-1][j][k][0]+DP[i-1][j][k-1][1]$

$DP[i][j][k][1]=DP[i-1][j-1][k-1][0]+DP[i-1][j-1][k][1] \quad (j!=0)$

递推范围

$FOR(1...i...200)\\\qquad FOR(0...j...200)\\\qquad\qquad FOR(1...k...20)$

代码

#include "cstdio"

#define LL long long

LL dp[205][205][25][2];

int main()

{

    //freopen("in.txt","r",stdin);

    int N,M,K;

    dp[0][0][0][0]=dp[0][0][0][1]=1;

    for(int i=1;i<=200;i++)

    {

        for(int j=0;j<=200;j++)

        {

            for(int k=1;k<=20;k++)

            {

                dp[i][j][k][0]=dp[i-1][j][k][0]+dp[i-1][j][k-1][1];

                if(j==0) continue;

                dp[i][j][k][1]=dp[i-1][j-1][k-1][0]+dp[i-1][j-1][k][1];

            }

        }

    }

    while(scanf("%d%d%d",&N,&M,&K)!=EOF)

        printf("%I64d\n",dp[N][M][K][0]+dp[N][M][K][1]);

}

 

 

S(0)=f(0)

S(1)=f(2)

S(2)=f(4)

S(n)=f(2n)

你可能感兴趣的:(HDU)