题目链接: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(2∗n)
时间: 2024-11-05 11:52:04