您的位置:首页 > 其它

09-02 HDU_Steps3.1 递推入门 HDU2041 HDU2044 HDU2045 HDU 2050 HDU2501 HDU2018 HDU1297 HDU2604

2011-09-08 23:21 417 查看
HDU Steps3.1 递推

3.1.1 HDU2041 超级楼梯 F(N)=F(N-1)+F(N-2)

3.1.2 HDU2044 一只小蜜蜂 F(N)=F(N-1)+F(N-2) N=终点-起点

3.1.3 HDU2018 母牛的故事 F(N)=F(N-1)+F(N-3)

3.1.4 HDU2050 折线分割平面 F(N)=2*N^2-N+1 递推,更简单的方法是用前三个点解三元一次方程组

3.1.5 HDU2501 Tiling_easy version F
=F(N-1]+2*F[N-2];

3.1.6 HDU2045 不容易系列之三-RGP难题 F
=F[N-1]+2*F[N-2]; F(1)=3,F[2]=6,F[3]=6

假如前N-1个是R------G 则第N个只能是B 一种选择

假如前N-2个是R------G则可以加RB或BG 两种选择

3.1.7 HDU1297 Children`s Queue F
=F[N-1]+F[N-2]+F[N-4];

F(n-1)+"M", F(n-2)+"FF", F(n-4)+"MFFF"

注意F(n-4)+"MF"不是要求序列,但再加上"FF"符合要求,所以要单独考虑.另外就是大数

3.1.8 HDU2604 Queuring

递推原理与上题类似F
=F[N-1]+F[N-3]+F[N-4];

但是直接O(N)的递推很慢,以前遇到过这题,用矩阵连乘可以加速到100MS左右(不优化4S+)

#include <cstdio>
using namespace std;
int st[5][5]={
{0,0,0,0,0},
{0,0,1,0,0},
{0,0,0,1,0},
{0,0,0,0,1},
{0,1,1,0,1},
};
struct jz{
int a[5][5];
//两种构造方法,一种清0,一种是相乘的矩阵
jz(int k){
if(k==0)for(int i=1;i<=4;i++)for(int j=1;j<=4;j++)a[i][j]=0;
if(k==1)for(int i=1;i<=4;i++)for(int j=1;j<=4;j++)a[i][j]=st[i][j];
}
//矩阵相乘,乘法过程中模m
jz mult(jz jz2,int m){
jz ans(0);
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
for(int k=1;k<=4;k++)
ans.a[i][j]=(ans.a[i][j]+a[i][k]*jz2.a[k][j])%m;
return ans;
}
//得到结果
int getr(){
return a[4][1]*2+a[4][2]*4+a[4][3]*6+a[4][4]*9;
}
};
jz dfs(int k,int m){
if(k==1)return jz(1);
//二分
jz rs=dfs(k/2,m);
jz ans=rs.mult(rs,m);
//处理为奇数的情况
if(k%2==1){
jz t2=jz(1);
jz tmp=ans.mult(t2,m);
ans=tmp;
}
return ans;
}

int main(){
int l,k;
int a[5]={1,2,4,6,9};
while(scanf("%d%d",&l,&k)!=EOF){
if(l<=4)printf("%d\n",a[l]%k);
else{
jz ans=dfs(l-4,k);
printf("%d\n",ans.getr()%k);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: