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)

posted @ 2015-06-12 20:54  Physcal  阅读(424)  评论(0编辑  收藏  举报