JDOJ-1064: 打倒美国帝国主义 高精度DP

[文章目录]

Description

美国企图利用帝国老鼠到中国传染病毒…他的病毒老鼠繁殖能力很强.
这种老鼠在出生后的第一个月,可以生出a 对老鼠;第二个月,可以生出b 对老鼠;
第三个月及以后的每个月,都可以生出c 对老鼠。
MZD对此十分担心,他很想知道,如果他有一对刚出生的老鼠,按最理想的模式繁殖,
且老鼠不死,那么最少需要多少个月它们就可以覆盖整个中国。
为了解决这个灭杀老鼠的问题,MZD需要知道这种老鼠在第N 个月时的数量,以便号召
群众除四害.a,b,c,N(0<=a<=b<=c<=100,N<=3000),

高精度DP,哈哈哈哈。(话说有些人说我刷水)。

其实我在练习自定义运算符。

其实 a=a+b;相当于'+'是一个函数,然后再a这个结构体里调用+这个函数。再赋值给a。

相当于:a=   a->+(b)的返回值;当然也可以直接在结构体函数里修改该结构体的值。

注意: '+'和'+='不是一个运算符。

另外,重载运算符的运算次序和之前的是一样的。(先乘除,后加减,大于小于,位运算都是一样的)

this指针在结构体函数里运用,表示引用这个函数的结构体的指针。

初始化函数如果不是定义指针(as splay)的话,直接node 就是初始化好的了。(玛丽有待提升,233,高精度写错了。。。)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int a,b,c,n,mod=1000000;//考虑到有*100的行为,所以直接压成陆位
bool flag=1;
struct node
{
    int a[1100];
    int len;
    node(){memset(a,0,sizeof(a));len=0;}
    node operator + (node x)
    {
        node ret;
        int t=0;
        ret.len=max(len,x.len);
        for(int i=1;i<=ret.len;i++)
        {
            ret.a[i]=(a[i]+x.a[i]+t)%mod;
            t=(a[i]+x.a[i]+t)/mod;
        }
        while(t) ret.a[++ret.len]=t%mod,t/=mod;//注意先%,后除
        return ret;
    }
    node operator * (int x)
    {
        node ret;
        if(x==0) return ret;
        int t=0;
        ret.len=len;
        for(int i=1;i<=ret.len;i++)
        {
            ret.a[i]=(a[i]*x+t)%mod;
            t=(a[i]*x+t)/mod;
        }
        while(t) ret.a[++ret.len]=t%mod,t/=mod;//注意是%,不是/
        return ret;
    }
    node operator +=(node x)//据某人所说,可以不设返回值。
    {
        *this=*this+x;//*this为结构体的名字。
        return *this;
    }
}f[2],g[2],h[2];
int main()
{
    cin>>a>>b>>c>>n;
    f[1].len=1;f[1].a[1]=1;
    for(int i=1;i<=n;i++)
    {
        f[flag^1]=f[flag]*a+g[flag]*b+h[flag]*c;
        g[flag^1]=f[flag];
        h[flag^1]=h[flag]+g[flag];
        flag^=1;
    }
    f[flag]+=g[flag];
    f[flag]+=h[flag];
    printf("%d",f[flag].a[f[flag].len]);
    for(int i=f[flag].len-1;i>0;i--)
        printf("%06d",f[flag].a[i]);
    return 0;
}

发表评论

邮箱地址不会被公开。 必填项已用*标注