JZOJ 4630 计数【NOIP2016提高A组模拟7.15】

计数

题目描述

这里写图片描述

输入格式

这里写图片描述

输出格式

这里写图片描述

样例输入

2 10

样例输出

90

数据范围

这里写图片描述

题解

Fi 表示当前 1 ~~ i 位已经算好时,有 Fi 个数满足题目条件,且第 i 位不为0。

如果上一位不为0,则方案数为 Fi1 (k1) ,如果上一位为0,显然方案数为 Fi2 (k1)

所以我们可以得到递推式 Fi = (k1) * (Fi1+Fi2)

考虑到这样答案会很大,而没有良心的出题人没有让我们加mod,所以我们只好打上个高精度乘法和高精度加法。

最后,答案即为 Fn

Code(Pascal)

const
    mo=100000000;
var
    f:array[-1..2000,0..5000] of int64;
    n,k,j,i,o,l:longint;
    p:int64;
function max(a,b:longint):longint;
    begin
        if a>b then exit(a)
        else exit(b);
    end;
procedure lj(o:longint);
    var
        i:longint;
        jw:int64;
    begin
        jw:=0;
        f[o,0]:=max(f[o-1,0],f[o-2,0]);
        for i:=1 to f[o,0] do
        begin
            f[o,i]:=f[o-1,i]+f[o-2,i]+jw;
            jW:=f[o,i] div mo;
            f[o,i]:=f[o,i] mod mo;
        end;
        while jw>0 do
        begin
            inc(f[o,0]);
            f[o,f[o,0]]:=jw mod mo;
            jw:=jw div mo;
        end;
    end;
procedure cf(o:longint);
    var
        i:longint;
        jw:int64;
    begin
        jw:=0;
        for i:=1 to f[o,0] do
        begin
            f[o,i]:=f[o,i]*(k-1)+jw;
            jw:=f[o,i] div mo;
            f[o,i]:=f[o,i] mod mo;
        end;
        while jw>0 do
        begin
            inc(f[o,0]);
            f[o,f[o,0]]:=jw mod mo;
            jw:=jw div mo;
        end;
    end;
begin
    readln(n,k);
    f[0,0]:=1;
    f[0,1]:=1;
    f[1,0]:=1;
    f[1,1]:=k-1;
    for i:=2 to n do
    begin
        lj(i);
        cf(i);
    end;
    write(f[n,f[n,0]]);
    for i:=f[n,0]-1 downto 1 do
    begin
        p:=f[n,i];
        o:=0;
        while p>0 do
        begin
            inc(o);
            p:=p div 10;
        end;
        for l:=1 to 8-o do
        write(0);
        write(f[n,i]);
    end;
end.

你可能感兴趣的:(高精度,一般动规与递推)