Yue Fei's Battle(组合计数递推)

//求一个直径为 k 的树有多少种形态,每个点的度不超过 3

// 非常完美的分析,学到了,就是要细细推,并且写的时候要细心

还有除法取模需要用逆元

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
using namespace std;
#define MOD 1000000007
#define LL long long
#define MX 100005

LL dp[MX];
LL sum[MX];
LL inv2;
LL inv6;

LL quick(LL a,LL b)
{
    LL ret = 1;
    while (b)
    {
        if (b&1) ret = ret*a%MOD;
        a = a*a%MOD;
        b/=2;
    }
    return ret;
}

void Init()
{
    inv2 = quick(2,MOD-2);
    inv6 = quick(6,MOD-2);
    dp[0]=1,sum[0]=1;
    dp[1]=1,sum[1]=2;
    for (int i=2;i<MX;i++)
    {
        dp[i] = dp[i-1]*(dp[i-1]-1)%MOD*inv2%MOD;
        dp[i] = (dp[i] + dp[i-1])%MOD;
        dp[i] = (dp[i] + dp[i-1]*sum[i-2]%MOD)%MOD;
        sum[i]=(sum[i-1]+dp[i])%MOD;
    }
}

int main()
{
    int n;
    Init();

    while (scanf("%d",&n)&&n)
    {
        if (n%2==0)
        {
            int i = n/2;
            int ans = (dp[i]+dp[i]*(dp[i]-1)/2)%MOD;
            printf("%d\n",ans);
        }
        else
        {
            int i = n/2;

            int ans = (((dp[i]*(dp[i]+1))%MOD*inv2%MOD)*sum[i-1])%MOD;

            ans = (ans + dp[i])%MOD;
            ans = (ans + (dp[i]*(dp[i]-1)%MOD)%MOD)%MOD;
            ans = (ans + dp[i]*(dp[i]-1)%MOD*(dp[i]-2)%MOD*inv6%MOD )%MOD;
            printf("%d\n",ans);
        }
    }
    return 0;
}

Yue Fei's Battle(组合计数递推)

时间: 2024-08-01 10:45:33

Yue Fei's Battle(组合计数递推)的相关文章

hdu 5136 Yue Fei&#39;s Battle(计数DP)

Yue Fei's Battle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Total Submission(s): 151    Accepted Submission(s): 48 Problem Description Yue Fei is one of the most famous military general in Chinese history.He

[hdu5136]Yue Fei&#39;s Battle 2014 亚洲区域赛广州赛区J题(dp)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 现场赛的时候由于有个地方有点小问题,没有成功AC,导致与金牌失之交臂. 由于今天下午有点事情,无法打重现,所以下午只是花了十分钟做了一道J题,抢了个FB,2333333333 Yue Fei's Battle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others)T

数的计数——递推算法

Problem Description 我们要求找出具有下列性质数的个数(包括输入的自然数n).先输入一个自然数n(n<=1000),然后对此自然数按照如下方法进行处理: 不作任何处理: 在它的左边加上一个自然数,但该自然数不能超过原数的一半: 加上数后,继续按此规则进行处理,直到不能再加自然数为止. Input 输入有多组数据,每组数据为自然数n. Output 对于每组数据输出满足条件的数的个数. Sample Input 6 Sample Output 6 Hint 满足条件的数为6,16

HDU 5136 Yue Fei&#39;s Battle

题意:求直径上有K个点的不同构树个数(每个点度不超过3). 二叉树满足每个点度不超过3,把直径从中间切开,两边就是二叉树了. 设dp[i] = 深度为i的不同构二叉树个数. sum[i] = 深度不超过i的不同构二叉树个数. 那么二叉树的两个分支有3种情况: 一个分支深度为i-1, 另一个分支深度小于i-1,有dp[i-1] * sum[i-2]种方法: 两个分支深度都是i-1,两个分支不一样,有dp[i-1]*(dp[i-1]-1)/2种方法: 两个分支深度都是i-1,两个分支一样,有dp[i

LA 4123 (计数 递推) Glenbow Museum

题意: 这种所有边都是垂直或水平的多边形,可以用一个字符串来表示,一个270°的内角记作O,一个90°的内角记作R. 如果多边形内存在一个点,能看到该多边形所有的点,则这个多边形对应的序列是合法的.这里长度不作限制,只要长度适当能满足要求即可. 现给出序列长度,问有多少种序列符合要求. 分析: 书上分析地很清楚,罗列一下要点: 首先对于一个长度为n的合法序列,R的个数为(n+4)/2,O的个数为(n-4)/2,即R比O多4个 我们要找的序列满足要求:R比O多4个,没有两个O相邻. 这里先设计了一

[bzoj1002][FJOI2007 轮状病毒] (生成树计数+递推+高精度)

Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图所示 N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不同的3轮状病毒,如下图所示 现给定n(N<=100),编程计算有多少个不同的n轮状病毒 Input 第一行有1个正整数n Output 计算出的不同的n轮状病毒数输出 Sample Input

hdn2049(错排加组合) 递推超时问题!!!!

http://acm.hdu.edu.cn/showproblem.php?pid=2049 不容易系列之(4)--考新郎 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 25945    Accepted Submission(s): 9493 Problem Description 国庆期间,省城HZ刚刚举行了一场盛大的集体婚礼,为

UVa 11361 (计数 递推) Investigating Div-Sum Property

题意: 统计[a, b]中有多少个数字满足:自身是k的倍数,而且各个数字之和也是k的倍数. 分析: 详细分析见<训练之南>吧,=_=|| 书上提出了一个模板的概念,有了模板我们就可以分块计算. 虽然书上定义f(x)表示不超过x的非负整数且满足条件的个数,但为了编码方便,代码中f(x)的含义为0~x-1中满足条件的个数. 这样最终所求为f(b+1) - f(a) 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int MOD

bzoj3244 树的计数 递推

这道题目bzoj上面真是丧心病狂,非要输出三个数(ans-0.001,ans,ans+0.001),mdzz.害的我还去抄了一发标程 首先按照bfs的顺序重新标号(比如样例那样),然后对于点x,令pos[x]为x的dfs序编号,a[i]为dfs序的第i个. 考虑每个点的贡献,如果pos[x]>pos[x+1],那么如果x和x+1同一层,显然pos[x]<pos[x+1],因此x+1必然在下一层,因此x+1的献为1. 另一方面,对于a[i]和a[i+1],显然a[i+1]要不是a[i]的儿子,要