BZOJ 1002 && Luogu 2144 [FJOI 2007] 轮状病毒

BZOJ题面

Luogu题面

蛤? DP不会啊

等等,有点不对,再看看......

 

蛤? 生成树计数基尔霍夫矩阵? No!

不行不行,再看看......

 

半个小时后,“看”的成果:

n 1 2 3

4

5 6
ans 1 = 1 * 1 5 = 3 * 3 - 4 16 = 4 * 4 45 = 7 * 7 - 4 121 = 11 * 11 320 = 18 * 18 - 4

(其中 1  3  4  7  11  18 ...... 为变形的斐波那契数列)

 

呵呵你懂得......

 

蛤?怎么 WA

哦,斐波那契数列好像是指数上升的...

 

so... 高精递推  AC

代码(带压行风格,大佬不喜勿喷

#include<bits/stdc++.h>
using namespace std;
int a[101][50],ans[50],n,s=1,k=1;
int main(){
    scanf("%d",&n);
    a[1][1]=1,a[2][1]=3;  // 初始化斐波那契数列
    for(int i=3;i<=n;i++){
        for(int j=1;j<=s;j++) a[i][j]=a[i-1][j]+a[i-2][j];  // 高精加
        for(int j=1;j<s;j++) if(a[i][j]>9) a[i][j]-=10,a[i][j+1]++;  // 处理进位
        if(a[i][s]>9) a[i][s]-=10,a[i][s+1]=1,s++;  // 最高位进位 s:位数
    }
    for(int i=1;i<=s;i++) for(int j=1;j<=s;j++) ans[i+j-1]+=a[n][i]*a[n][j];  // 高精乘(乱搞)
    for(int i=1;i<=s*2-1;i++) ans[i+1]+=ans[i]/10,ans[i]%=10;  // 进位
    if(!(n%2)) ans[1]-=4;  // 减法
    while(ans[k]<0) ans[k]+=10,k++,ans[k]--;  // 处理退位
    if(ans[s*2]) printf("%d",ans[s*2]);     // 从高位到低位
    for(int i=s*2-1;i>0;i--) printf("%d",ans[i]);  // 输出
    return 0;
}

(找规律大法好)

DP Dalao 可以告诉蒟蒻怎么做哦!

 

By  The_Seventh

2017-12-28  20:49:11

posted @ 2017-12-28 20:50  The_Seventh  阅读(169)  评论(0编辑  收藏  举报