Children’s Queue HDU 1297 递推+大数
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1297
题目大意:
有n个同学, 站成一排, 要求 女生最少是两个站在一起, 问有多少种排列方式。
题目分析:
1. 假设第n个学生是个男生, 我们可以直接将他放在最后有 dp[n-1]种
即: ...............M dp[n-1]
2.假设第n个放女生,要求两个女生在一起, 我们可以直接在最后放两个女生
即: .............FF dp[n-2]
3.假设我们后面放两个女生, 但之前的序列最后两个是 一个男生+一个女生即: ...........MF 序列
明显是不合法的, 但是我们后面要是再加上两个 女生就能使这个原来不合法的序列变的合法
即 ................MF FF dp[n-4]
综上:我们的递推式子为: dp[n] = dp[n-1] + dp[n-2] + dp[n-4];
因为数据量为1000 所以我们用大数来进行运算
#include <iostream> #include <queue> #include <cstdio> #include <cstring> #include <cstdlib> #include <stack> #include <algorithm> #include <vector> #include <string> #include <cmath> using namespace std; const long long maxn =1005; const long long INF = 0xfffffff; int dp[maxn][maxn]; void Slove() { dp[0][0] = 1; dp[1][0] = 1; dp[2][0] = 2; dp[3][0] = 4; for(int i=4; i<maxn; i++) { for(int j=0; j < maxn; j++) { dp[i][j] += dp[i-1][j] + dp[i-2][j] + dp[i-4][j]; dp[i][j+1] += dp[i][j]/10; dp[i][j] %= 10; } } } void Putt(int n) { int i; for(i = maxn - 1; i >= 0; i--) if(dp[n][i]) break; for(; i>0; i--) printf("%d",dp[n][i]); printf("%d ",dp[n][i]); } int main() { int n; Slove(); while(cin >> n) { Putt(n); } return 0; }