【递推】【高精度】【FJOI 2007】【bzoj 1002】轮状病毒

1002: [FJOI2007]轮状病毒

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 3238  Solved: 1797

Description

给定n(N<=100),编程计算有多少个不同的n轮状病毒。

Input

第一行有1个正整数n。

Output

将编程计算出的不同的n轮状病毒数输出

Sample Input

3

Sample Output

16

题解:

递推。

打表可以找规律得,f[i]=3*f[i-1]-f[i-2]+2,但是需要高精度。。

还可以找更神奇的规律,和卢卡斯数列相关——>这里是卢卡斯数列相关的做法——by Vampire

Code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;

int n,f[110][110];

void jia(int x,int y){
    f[x][1]+=y;
    for (int i=1; i<=f[x][0]; i++)
        if (f[x][i]>9)
            f[x][i+1]+=f[x][i]/10,f[x][i]%=10;
    if (f[x][f[x][0]+1]) f[x][0]++;
}
void jian(int x,int y){
    int c[110];
    for (int i=0; i<=f[x][0]; i++) c[i]=f[x][i];
    for (int i=1; i<=f[y][0]; i++){
        if (c[i]<0) c[i+1]--,c[i]+=10;
        int s=c[i]-f[y][i];
        if (s<0) c[i+1]--,s+=10;
        c[i]=s;
    }
    for (int i=f[y][0]+1; i<=c[0]; i++)
        if (c[i]<0) c[i+1]--,c[i]+=10;
    while (!c[c[0]]) c[0]--;
    for (int i=0; i<=c[0]; i++) f[x][i]=c[i];
}
void cheng(int x,int y,int z){
    int c[110]; f[x][0]=f[y][0];
    for (int i=0; i<=f[y][0]; i++) c[i]=f[y][i];
    for (int i=1; i<=c[0]; i++){
        c[i]*=z;
        if (c[i]>9)
            f[x][i+1]+=c[i]/10,c[i]%=10;
        f[x][i]+=c[i];
    }
    if (f[x][f[x][0]+1]) f[x][0]++;
}

void dp(){
    memset(f,0,sizeof(f));
    f[1][++f[1][0]]=1,f[2][++f[2][0]]=5;
    for (int i=3; i<=n; i++)
        cheng(i,i-1,3),jian(i,i-2),jia(i,2);
}

void out(){
    for (int i=f[n][0]; i>=1; i--)
        printf("%d",f[n][i]);
    printf("\n");
}

int main(){
    scanf("%d",&n);

    dp(); out();

    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-15 15:42:54

【递推】【高精度】【FJOI 2007】【bzoj 1002】轮状病毒的相关文章

BZOJ 1089 严格n元树 (递推+高精度)

题解:用a[i]表<=i时有几种树满足度数要求,那么这样就可以递归了,a[i]=a[i-1]^n+1.n个节点每个有a[i-1]种情况,那么将其相乘,最后加上1,因为深度为0也算一种.那么答案就是a[n]-a[n-1].然后就是高精度的问题了,发现很久没有现码高精度没手感了,连高进度加法进位都出了些问题,需要特别注意. #include <cstdio> #include <cstring> #include <algorithm> using namespace

BZOJ 1002 轮状病毒(生成树个数)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1002 题意:求下面这种造型的生成树的个数. 思路:生成树的个数可以用那个矩阵 A:A[i][i]等于i的度数,A[i][j]等于i到j的边数的相反数.那么A的任意一个n-1阶的行列式(就是删掉任意一行一列)就是生成树的个 数.但是这里有一个递推公式,暴力完前几项可以找出这个,f[n]=3*f[n-1]-f[n-2]+2. import java.util.*; import java.

递推 + 高精度 --- Tiling

Tiling Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7264   Accepted: 3528 Description In how many ways can you tile a 2xn rectangle by 2x1 or 2x2 tiles? Here is a sample tiling of a 2x17 rectangle. Input Input is a sequence of lines,

递推+高精度+找规律 UVA 10254 The Priest Mathematician

题目传送门 1 /* 2 题意:汉诺塔问题变形,多了第四个盘子可以放前k个塔,然后n-k个是经典的汉诺塔问题,问最少操作次数 3 递推+高精度+找规律:f[k]表示前k放在第四个盘子,g[n-k]表示经典三个盘子,2 ^ (n - k) - 1 4 所以f[n] = min (f[k] * 2 + g[n-k]),n<=10000,所要要用高精度,另外打表能看出规律 5 */ 6 /************************************************ 7 * Auth

POJ 2506 Tiling (递推+高精度)

[题目链接]click here~~ [题目大意] In how many ways can you tile a 2xn rectangle by 2x1 or 2x2 tiles? Here is a sample tiling of a 2x17 rectangle. [解题思路]: (1)一个2*2的格子有三种填充方法: 两个横着放, 两个竖着放, 放一个2*2 (2)得出递推公式F[i]=F[i-1]+F[i-2]*2 然后就是套高精度模板了 代码; /* Author:HRW 递推+

[luogu]P1066 2^k进制数[数学][递推][高精度]

[luogu]P1066 2^k进制数 题目描述 设r是个2^k 进制数,并满足以下条件: (1)r至少是个2位的2^k 进制数. (2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位. (3)将r转换为2进制数q后,则q的总位数不超过w. 在这里,正整数k(1≤k≤9)和w(k<W≤30000)是事先给定的. 问:满足上述条件的不同的r共有多少个? 我们再从另一角度作些解释:设S是长度为w 的01字符串(即字符串S由w个“0”或“1”组成),S对应于上述条件(3)中的q

BZOJ 1002 FJOI2007 轮状病毒 递推+高精度

题目大意:轮状病毒基定义如图.求有多少n轮状病毒 这个递推实在是不会--所以我选择了打表找规律 首先执行下面程序 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 110 using namespace std; struct abcd{ int to,next; bool ban; }table[M<<2]; int head[

【BZOJ】1089: [SCOI2003]严格n元树(递推+高精度/fft)

http://www.lydsy.com/JudgeOnline/problem.php?id=1089 想了好久的递推式,,,然后放弃了QAQ 神思路!orz 首先我们设$f[i]$表示深度最大为i的n元树的数目,注意,是最大深度为i! 那么易得递推式 f[i]=f[i-1]^n+1 前面表示子树的情况乘积,后面表示树为1层!因为1层是合法的!即没有子女! 然后答案就是 f[d]-f[d-1] !!!为什么要剪掉呢?因为看我们的转移,并不是深度为i,而是深度最大为i,那么为什么要这样减呢?理由

[BZOJ1089][SCOI2003]严格n元树(递推+高精度)

题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1089 分析: 第一感觉可以用一个通式求出来,但是考虑一下很麻烦,不好搞的.很容易发现最底层必有一个是满高度的,其他的任意. 所以直接的递推也不好想. (以下所述都是n元树) 于是可以令f[d]为深度<=d的树的个数,那么深度为d的就是f[d]-f[d-1] 对于深度<=d的又该怎么处理呢? 考虑第一层的n个点(根为0层),每个点都要底下连子树,深度为0~i-1,方案数即f[d-1]

HDU 1041[Computer Transformation] 递推 高精度

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1041 题目大意:初始数字1.规则1变成01,0变成10.问经过N次完整变换后,有多少连续零对. 关键思想:考虑零对的直接来源只有"10",而"10"的直接来源只有"1"或者"00".于是可以得到以下几种递推式 1. dp[i]=pow(2,i-3)+dp[i-2];当前层多少1,下一层就多少10,下下层就多少00:当前层多少00,