题目链接:点击查看

题目大意:规定宽度为4,给定长度为n,求用1*2和2*1的瓷砖,将其完全铺满能有多少种方法。

分析:自从学会了矩阵快速幂之后,看到1e18的数据量都会下意识的往递推上面想,但是以前都是因为找不到规律而止步不前。今天看到了一个大佬的博客之后,学会了一个新的方法,这个方法学长上课也讲了,如果按照正规做法的话应该用高斯消元法求递推式,但是相应的,用暴力的手法也能硬凑出递推关系式:https://www.cnblogs.com/yzm10/p/9313916.html

2020.7.18更新:

大半夜睡不着觉回顾以前的博客,发现这个题不就是个杜教BM嘛,爆搜找出前10项然后直接套上模板就过了

注意有一点,利用这个方法只能解决线性问题,非线性的规律是不能用这个方法处理的

第一步:通过暴搜找出前几个数据:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e4+200;int n,ans;bool vis[N][N];void dfs(int s)//s代表已放置瓷砖面积
{if(s==4*n){ans++;return;}for(int i=0;i<4;i++)for(int j=0;j<n;j++){if(!vis[i][j]){if(i+1<4&&!vis[i+1][j]){vis[i+1][j]=vis[i][j]=true;dfs(s+2);vis[i+1][j]=vis[i][j]=false;}if(j+1<n&&!vis[i][j+1]){vis[i][j+1]=vis[i][j]=true;dfs(s+2);vis[i][j+1]=vis[i][j]=false;}return;}}
}int main()
{
//  freopen("input.txt","r",stdin);while(scanf("%d",&n)!=EOF){memset(vis,false,sizeof(vis));ans=0;dfs(0);cout<<n<<": "<<ans<<endl; }return 0;
}

可以得到的数据:1 5 11 36 95 281 781 2245 6336 18061 51205 145601

第二步:通过for循环寻找系数:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e4+200;int a[]={1,5,11,36,95,281,781,2245,6336,18061,51205,145601};int main()
{
//  freopen("input.txt","r",stdin);for(int a1=-20;a1<=20;a1++)for(int a2=-20;a2<=20;a2++)for(int a3=-20;a3<=20;a3++)for(int a4=-20;a4<=20;a4++)for(int a5=-20;a5<=20;a5++)for(int a6=-20;a6<=20;a6++)for(int i=0;i+6<12;i++)if(a1*a[i]+a2*a[i+1]+a3*a[i+2]+a4*a[i+3]+a5*a[i+4]+a6*a[i+5]==a[i+6])if(i==5&&a1==0)cout<<a6<<' '<<a5<<' '<<a4<<' '<<a3<<' '<<a2<<' '<<a1<<endl;return 0;
}

找到末尾0的个数较多的一项,在本题中即1 5 1 -1 0,故递推公式为dp[i]=dp[i-1]+5*dp[i-2]+dp[i-3]-dp[i-4]

第三步:矩阵快速幂模板

上代码之前有个小细节要注意,就是矩阵中涉及到了负数,而负数直接运算取模会出现异常错误,所以为了避免此类错误,我们在取模的时候要稍微处理一下,可以有两种方法:

  1. 先取模再运算
  2. 先运算再取模

我这里用的是先运算再取模,上代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<sstream>
#include<cmath>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=4;//a[i]=a[i-1]+5*a[i-2]+a[i-3]-a[i-4]const LL mod=1000000007;struct M
{LL a[N][N];
};M operator*(M a,M b)
{M temp;memset(temp.a,0,sizeof(temp.a));for(LL i=0;i<N;i++)for(LL j=0;j<N;j++){temp.a[i][j]=0;for(LL k=0;k<N;k++){temp.a[i][j]=(temp.a[i][j]+(a.a[i][k]*b.a[k][j]+mod)%mod)%mod;}}return temp;
} M q_pow(M a,LL n)
{M ans;memset(ans.a,0,sizeof(ans.a));for(LL i=0;i<N;i++)ans.a[i][i]=1;while(n){if(n&1)ans=ans*a;a=a*a;n>>=1;}return ans;
}int main()
{
//  freopen("input.txt","r",stdin);LL n;while(scanf("%lld",&n)!=EOF){if(n==1){cout<<1<<endl;continue;}else if(n==2){cout<<5<<endl;continue;}else if(n==3){cout<<11<<endl;continue;}else if(n==4){cout<<36<<endl;continue;}M start;memset(start.a,0,sizeof(start.a));start.a[0][0]=start.a[0][1]=start.a[1][2]=start.a[2][3]=start.a[2][0]=1;start.a[1][0]=5;start.a[3][0]=-1;M ans;memset(ans.a,0,sizeof(ans.a));ans.a[0][0]=36;ans.a[0][1]=11;ans.a[0][2]=5;ans.a[0][3]=1;M res=q_pow(start,n-4);cout<<(ans*res).a[0][0]<<endl;
/*      M temp=q_pow(start,2);temp=ans*temp;for(int i=0;i<N;i++){for(int j=0;j<N;j++)cout<<temp.a[i][j]<<' ';cout<<endl;}*/}return 0;
} 

杜教BM:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <cassert>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1000000007;
ll powmod(ll a,ll b)
{ll res=1;a%=mod;assert(b>=0);for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;
}
int _,n;
namespace linear_seq {const int N=10010;ll res[N],base[N],_c[N],_md[N];vector<int> Md;void mul(ll *a,ll *b,int k) {for(int i = 0 ; i < k + k ; ++i)_c[i]=0;for(int i = 0 ; i < k ;++i)if (a[i])for(int j = 0 ;j < k ;++ j)_c[i+j]=(_c[i+j]+a[i]*b[j])%mod;for (int i=k+k-1;i>=k;i--)if (_c[i])for(int j = 0 ; j<(int ) Md.size() ; ++ j)_c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;for(int i =0 ; i< k ; ++i)a[i]=_c[i];}int solve(ll n,VI a,VI b) {ll ans=0,pnt=0;int k=SZ(a);assert( SZ(a) == SZ(b) );for(int i = 0 ;i < k ; ++ i)_md[k-1-i] = -a[i] ; _md[k] = 1 ;Md.clear() ;for(int i =0 ; i < k ; ++ i)if (_md[i]!=0)Md.push_back(i);for(int i = 0; i< k ;++ i)res[i]=base[i]=0;res[0]=1;while ((1ll<<pnt)<=n)pnt++;for (int p=pnt;p>=0;p--) {mul(res,res,k);if ((n>>p)&1) {for (int i=k-1;i>=0;i--) res[i+1]=res[i];res[0]=0;for(int j = 0 ;j < (int)Md.size() ; ++ j)res[ Md[j] ]=(res[ Md[j] ]-res[k]*_md[Md[j]])%mod;}}rep(i,0,k) ans=(ans+res[i]*b[i])%mod;if (ans<0) ans+=mod;return ans;}VI BM(VI s) {VI C(1,1),B(1,1);int L=0,m=1,b=1;for(int n= 0 ;n < (int)s.size(); ++ n ) {ll d=0;for(int i =0 ; i < L +1 ;++ i)d=(d+(ll)C[i]*s[n-i])%mod;if (d==0) ++m;else if (2*L<=n) {VI T=C;ll c=mod-d*powmod(b,mod-2)%mod;while (SZ(C)<SZ(B)+m)C.push_back(0);for(int i =0 ; i < (int)B.size(); ++ i)C[i+m]=(C[i+m]+c*B[i])%mod;L=n+1-L; B=T; b=d; m=1;} else {ll c=mod-d*powmod(b,mod-2)%mod;while (SZ(C)<SZ(B)+m)C.push_back(0);for(int i = 0 ;i <(int) B.size() ; ++ i)C[i+m]=(C[i+m]+c*B[i])%mod;++m;}}return C;}ll gao(VI a,ll n) {VI c=BM(a);c.erase(c.begin());for( int i = 0 ; i < (int)c.size( );++i )c[i]=(mod-c[i])%mod;return (ll)solve(n,c,VI(a.begin(),a.begin()+SZ(c)));}
};
int main() {long long n;VI a;int N,v;a.push_back(1);a.push_back(5);a.push_back(11);a.push_back(36);a.push_back(95);a.push_back(281);a.push_back(781);a.push_back(2245);a.push_back(6336);a.push_back(18061);a.push_back(51205); for (;~scanf("%lld",&n);)printf("%lld\n",linear_seq::gao(a,n-1));return 0 ;
}

HDU - 6185 Covering(暴搜+递推+矩阵快速幂/杜教BM)相关推荐

  1. 湘潭赛Easy wuxing(递推+矩阵快速幂or DP)

    湘潭赛Easy wuxing(递推+矩阵快速幂or DP) 十分感谢老师的思路! 题目描述 "五行"是中国传统哲学思想,它认为认为大自然的现象由"木.火.土.金.水&qu ...

  2. Recursive sequence HDU - 5950 (递推 矩阵快速幂优化)

    题目链接 F[1] = a, F[2] = b, F[i] = 2 * F[i-2] + F[i-1] + i ^ 4, (i >= 3) 现在要求F[N] 类似于斐波那契数列的递推式子吧, 但 ...

  3. 递推+矩阵快速幂 HDU 2065

    1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 5 using namespace ...

  4. 【递推矩阵快速幂】hdu 2604

    前四位我们可以算出d[1]=2,d[2]=4,d[3]=6,d[4]=9.    我们可以这样想:一个合法串可以由两个较短的合法串组成    就以d[n]为例:(注意不能重复)    1.n-1个字符 ...

  5. Happy Necklace dp 递推 矩阵快速幂

    当满足素数2和素数3的条件后,下一个素数区间5乃至之后的都会被满足. 考虑能否从f[n - 1]转换到f[n],考虑第i - 1位,如果后面加红色一定满足条件,所以f[n]先是加上f[n - 1] 如 ...

  6. POj 3420 Quad Tiling 状态压缩DP+递推+矩阵快速幂

    哈哈,写了好久的,总算对了. 接下来介绍两种思路: 先介绍一种   递推+矩阵的快速幂的方法 一种DP的思想考虑4×n的最后一列  ,可以放的方法一共有5种 1.放4个 1×2  则 为dp[n-2] ...

  7. HDOJ 2604 Queuing (递推+矩阵快速幂)

    点击打开链接 题意:给你一个长度为L的由m和f两种字母组成的字符串,定义存在fmf以及fff子串的都是不符合要求的串,问长度为L的符合要求的串有多少个? 解题思路: 首先找出递推关系式,先给出递推关系 ...

  8. NYOJ 1075 (递推 + 矩阵快速幂)

    "红色病毒"问题 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 医学研究者最近发现了一种新病毒,因为其蔓延速度与曾经在Internet上传播的&qu ...

  9. 【HDU - 4990】 Reading comprehension (构造+矩阵快速幂)

    题干: Read the program below carefully then answer the question.  #pragma comment(linker, "/STACK ...

最新文章

  1. python教程实例-Python中函数的用法实例教程
  2. 动态规划经典例题:乘积最大连续子数组
  3. 蓝桥杯_算法训练_ALGO12_摆动序列
  4. 【Java】计算一组同学一门课程的平均成绩、最高成绩和最低成绩
  5. 这家公司把三星、联想、微软等7家公司给告了 侵犯其触摸屏专利
  6. 运动:延伸你的美丽(图)
  7. python画椭圆的逻辑_在Python中绘制椭圆轨道(使用numpy,matplotlib)
  8. atmega168p与328p_ATMEGA328P-MU产品说明
  9. 普元EOS7.5生成入参为数组的WebService接口
  10. CSS 实现圆角梯形
  11. 将自家的位置标注到地图上(51ditu.com)
  12. graphpad两组t检验_GraphPad prism -- t检验操作步骤解析~
  13. 读《JOINT AND ADVERSARIAL TRAINING WITH ASR FOR EXPRESSIVE SPEECH SYNTHESIS》
  14. Chapter 76 - 89
  15. 解决mysql ERROR 2002 (HY000): Can't connect to local MySQL server through socket错误的方法
  16. 高德地图去掉定位按钮_高德地图自定义定位按钮及点击事件
  17. AI时代,与其恐惧,不如拥抱。
  18. 深度解析FPS游戏外挂形成原因与“破局”方案
  19. nexus运行时异常org.apache.http.conn.ConnectTimeoutException
  20. Portal-Gateway路由网关

热门文章

  1. Hystrix仪表盘解释
  2. MyBatis 插件原理与自定义插件-代理和拦截是怎么实现的?
  3. Spring-Cloud中常见的服务组件
  4. SpringMVC的数据响应
  5. 自定义工具类:导入工具类测试
  6. 数据库-mysql基础操作之输入查询
  7. 互联网API开放平台安全设计-基于OAuth2.0协议方式
  8. 函数基本使用-函数的定义以及调用执行线路图
  9. Oracle数据库的安装和配置
  10. Zookeeper_zkClientListener讲解