ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

凌乱的地下室

2022-06-15 21:03:32  阅读:173  来源: 互联网

标签:ch 地下室 ll dfs notag long bmatrix 凌乱


P2100 凌乱的地下室

思路一

注:由于本题数据过大,这里只讲解思路以及 $ 50 $ 分代码,高精度请自便。

不妨设当有 \(n\) 个方块时,可能的摆放数为 $f(n) $ 。

显然\(f(1)=1,f(2)=2\)。

当计算 \(f(3)\) 时,不妨进行模拟(用\(1,2,3..\)代表方块):

\[这是f(2)的情况 \begin{bmatrix} \notag 1&2\\ 2&1 \end{bmatrix} \\\notag 显然,计算f(3)时应从以上两种状况转移: \begin{bmatrix} \notag 1&2&3\\ 1&3&2\\ 2&1&3 \end{bmatrix} \\ \therefore f(3)=3\\ \]

不妨我们再模拟一下\(f(4)\):

\[\notag f(3)=3 ~~ \begin{bmatrix} \notag 1&2&3\\ 1&3&2\\ 2&1&3 \end{bmatrix} \\ 模拟f(4): \begin{bmatrix} \notag 1&2&3&4\\ 1&2&4&3\\ 1&3&2&4\\ 2&1&3&4\\ 2&1&4&3 \end{bmatrix} \\\therefore f(4)=5 \]

由此我们可以大概猜测:数列\(f(n)\)是以\(1,2\)为前两项的斐波那契数列。

其实到这里已经可以做题了,但作为一名优秀的数学学子,这种不完全归纳法是不一定正确的,所以我们不妨浅证明一下:

可以看到,当由 \(n-1\) 递推 \(n\) 时,只有最后一个数为 \(n-1\) 的情况才会产生两种情况,而其他都只会有一种。

\[\notag eg: \\ n=3 ~~~ \begin{bmatrix} \notag 1&2&3&(1)\\ 1&3&2&(2)\\ 2&1&3&(3) \end{bmatrix} \\ n=4时,只有(1)(3)行可以产生2个的情况而(2)仅会产生一种情况\\ 而接下来又会有4行的末尾为4,当递推n=5时就会有四行可以产生两种情况。 \]

而这个末尾为\(n\)的情况是如何产生的呢?

自然是在\(n-1\)的每一重情况后面都加上一个\(n\)就得到了。

由此可得:

\[\notag n>=2时,f(n)=f(n-1)+f(n-2) \]

再用数学归纳法证明即可。

CODE(50tps)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn = 3123123;
ll ll_maxn=1e18;
inline ll read_int(){
    ll a=0,f=0,g=getchar();
    while(g<'0'||g>'9'){if(g=='-') f=1;g=getchar();}
    while('0'<=g&&g<='9') a=a*10+g-'0',g=getchar();
    return f ? -a : a;
}

inline void write(ll s,bool f){
    ll top=0,a[40];
    if(s<0) s=-s,putchar('-');
    while(s) a[++top]=s%10,s/=10;
    if(top==0) a[++top]=0;
    while(top) putchar(a[top]+'0'),top--;
    if(f) putchar('\n');
}

const ll mod=1e8; 
const ll maxm = 5;
struct JZ{
    ll jz[maxm][maxm];
    ll m,n;
    inline void clear(){memset(jz,0,sizeof jz),n=0,m=0;}
    JZ operator * (JZ a) const{
        JZ b;
        b.clear();
        b.m=m,b.n=a.n;
        for(ll i=1;i<=b.m;i++){
            for(ll e=1;e<=b.n;e++){
                for(ll k=1;k<=n;k++){
                    b.jz[i][e]+=jz[i][k]*a.jz[k][e];
                    b.jz[i][e]%=mod;
                }
            }
        }
        return b;
    }
    inline void _write(){
        for(ll i=1;i<=m;i++){
            for(ll e=1;e<=n;e++){
                write(jz[i][e],0),putchar(' ');
            }
            puts("");
        }
    }
    inline void build(ll M,ll N){
        clear();
        m=M,n=N;
        for(ll i=1;i<=m;i++){
            for(ll e=1;e<=n;e++){
                jz[i][e]=read_int();
            }
        }
    }
    inline void bz(ll N){
        clear();
        n=m=N;
        for(ll i=1;i<=n;i++) jz[i][i]=1;
    }
};

inline void read(){
	JZ a1,b1;
	ll n=read_int()-1;
	a1.clear();
	a1.m=2,a1.n=1;
	a1.jz[1][1]=1,a1.jz[2][1]=2;
	b1.bz(2);
	JZ a2;
	a2.clear();
	a2.m=a2.n=2;
	a2.jz[1][1]=0,a2.jz[1][2]=1,a2.jz[2][1]=1,a2.jz[2][2]=1;
	while(n){
		if(n&1) b1=b1*a2;
		a2=a2*a2,n>>=1;
	}
	a1=b1*a1;
	write(a1.jz[1][1],1);
}

int main (){
	ll T=read_int();
	while(T--)	read();
}

思路二

既然知道了是斐波那契数列,为什么不直接用其通项公式计算呢?

CODE(100tps)

//题解 
#include<bits/stdc++.h>
using namespace std;
map<long long ,long long>mmp;     //map优化递归求斐波拉契
long long a,b,c,d;
long long dfs(long long a){
	if(a==1) return 1;
	if(a==2) return 1;
	if(mmp[a]!=0) return mmp[a];
	else return 
		mmp[a]=a%2==0?(dfs(a/2)+2*dfs(a/2-1))*dfs(a/2)%100000000 :
		 (dfs(a/2)*dfs(a/2)+dfs(a/2+1)*dfs(a/2+1))%100000000;
}        //通项公式求斐波拉契
inline long long read(){
	long long X=0;char ch=getchar();
	while(!isdigit(ch)) ch=getchar();
	while(isdigit(ch)) X=(X*10+ch-'0')%150000000,ch=getchar();
	return X;
}     //取摸150000000直接在快速读入中进行
int main(){
	a=read();
	cout<<dfs(a+1);
}          //主程序真短

标签:ch,地下室,ll,dfs,notag,long,bmatrix,凌乱
来源: https://www.cnblogs.com/LQX-OI/p/16379801.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有