2017.10.13 轮状病毒 失败总结

这个题可以用矩阵树定理,构造基尔霍夫矩阵,然后直接求行列式。。

但这样做会被卡精度,所以需要考虑有没有递推的做法

首先想按联通块个数来分状态,但除个数外,还有每个联通块的大小也会影响答案,

所以这是不能离散的,然后枚举是n!,,然后尝试打表找规律,发现奇数个都是二次方,偶数个都是5*二次方

然后把它们列下来会发现前两项是1,下一项是3,自然想到斐波那契,然后我就考虑差值了,偶数直接是项,但并没有想到奇数怎么算

然后正解是利用行列式的性质进行行行相减,然后减成一个递推式:


码(高精写得好熟啊):

#include<iostream>
#include<cstdio>
using namespace std;
int n,f[105][2005],i,j,jw;
int main()
{
	scanf("%d",&n);
	f[1][1]=f[1][0]=f[2][0]=1;
    f[2][1]=5;
	for(i=3;i<=n;i++)
	{
		f[i][0]=f[i-1][0];
	jw=0;
	for(j=1;j<=f[i-1][0];j++)
	{
		int lin=jw;
	jw=(f[i-1][j]*3+lin)/10;
	f[i][j]=(f[i-1][j]*3+lin)%10;	
	}	
	if(jw>0)f[i][++f[i][0]]=jw;	
	jw=0;
	for(j=1;j<=f[i][0];j++)
	{
		f[i][j]=f[i][j]-f[i-2][j]-jw;
jw=0;
if(f[i][j]<0)f[i][j]+=10,jw=1;
	}
	while(f[i][f[i][0]]==0)f[i][0]--;
f[i][1]+=2;
for(j=1;j<=f[i][0];j++)
	{
if(f[i][j]>=10)f[i][j]-=10,f[i][j+1]++;		
	}		
		if(f[i][f[i][0]+1]>0)f[i][0]++;
	}
	for(i=f[n][0];i>=1;i--)
	printf("%d",f[n][i]);	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值