hdu 2604(WA)

其实发的这篇博文是个问题贴,,,大神愿意的话可以帮我解决一下,先发出来保存,日后必搞懂

首先dp还是能明显看出来的就是递推关系,设f(n)为n个人满足条件的方案数。如果最后一个人是m不用说了,前面就是f(n-1),如果最后是f的话,最后三个要么是mmf 要么是mff。如果是mmf那么这最后三个元素不会对前面造成任何影响,所以方案数是f(n-3),如果最后是mff,则倒数第四个肯定是m,此时方案数为f(n-4),所以递推关系是f(n)=f(n-1)+f(n-3)+f(n-4);

变成了矩阵快速幂经典问题:pic

用模板求解(这里用的是最短路得那个模板) 然后WA了。。。桑心

WA:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int MAX=4;        
ll sum[MAX][MAX],array[MAX][MAX];
int m,l;        
void MatrixMult(ll a[MAX][MAX],ll b[MAX][MAX]){//矩阵相乘   
    ll c[MAX][MAX]={0};    
    for(int i=0;i<4;++i){    
        for(int j=0;j<4;++j){    
            for(int k=0;k<4;++k){    
                c[i][j]=c[i][j]+a[i][k]*b[k][j]%m;    
            }
			c[i][j]%=m;    
        }    
    }    
    for(int i=0;i<4;++i){    
        for(int j=0;j<4;++j)a[i][j]=c[i][j];    
    }    
}    
    
void Matrix(int kk){//矩阵快速幂
	ll f[4][4]={{1,0,1,1},{1,0,0,0},{0,1,0,0},{0,0,0,1}};     
    for(int i=0;i<4;++i){//初始化矩阵sum,使sum*b=b(b是矩阵)     
        for(int j=0;j<4;++j){    
            if(i == j)sum[i][j]=1;    
            else sum[i][j]=0;    
        }    
    }    
    for(int i=0;i<4;++i){//将最初矩阵f复制给array     
        for(int j=0;j<4;++j)array[i][j]=f[i][j];    
    }    
    while(kk){    
        if(kk&1)MatrixMult(sum,array);    
        MatrixMult(array,array);    
        kk>>=1;    
    }        
}  
int main()
{
	
	int key;
	while(scanf("%d %d",&l,&m)==2)
	{
		if(l==1)
		cout<<2%m<<endl;
		else if(l==2)
		cout<<4%m<<endl;
		else if(l==3)
		cout<<6%m<<endl;
		else if(l==4)
		cout<<9%m<<endl;
		else if(!l)
		cout<<0<<endl;
		else
		{
			Matrix(l-4);
			/*for(int i=0;i<4;i++)
				{for(int j=0;j<4;j++)
					{cout<<sum[i][j]<<" ";}
					cout<<endl;}*/						
			key=(sum[0][0]*9%m+sum[0][1]*6%m+sum[0][2]*4%m+sum[0][3]*2%m)%m;
			cout<<key<<endl;
		}
	}
	return 0;
}

可能是模板问题吧,,,或者还是没有理解模板 orz(日后必补上)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值