BZOJ 1002 && Luogu 2144 [FJOI 2007] 轮状病毒
蛤? 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