您的位置:首页 > 其它

动态规划之简单递推(HDU2041,HDU2044,HDU2045,HDU2046,HDU2047)

2014-10-22 16:28 344 查看
递推可以说是动态规划的核心思想,下面总结了杭电上几道比较简单的递推题目:

HDU2041 超级楼梯:

题目大意:有n阶台阶,你在第一阶,每次只能向上走一步或两步,问你上到第n阶一共有多少种不同的方法数。

易知M=2时N=1,M=3时N=2,M>3时,有F【M】=F【M-1】+F【M-2】,即到达第M阶楼梯的方法数等于到达M-1阶楼梯的数目加上到达M-2阶楼梯的数目。

实质就是斐波那契数列,鉴于n的范围比较小,打表就行。

#include <cstdio>

#include <iostream>
using namespace std;
int ans[45];
void init()
{
ans[2]=1;
ans[3]=2;
for(int i=4;i<42;i++)
ans[i]=ans[i-1]+ans[i-2];
}
int main()
{
init();
int t,n;
cin>>t;
while(t--)
{
scanf("%d",&n);
printf("%d\n",ans
);
}
return 0;

}


HDU2044 一只小蜜蜂:

这题和2041实质是一样的,把从a到b的路线数看为从1到b-a+1的路线数的话,其实就是斐波那契数列。

#include <cstdio>
#include <iostream>
using namespace std;
long long ans[55];
void init()
{
ans[2]=1;
ans[3]=2;
for(int i=4;i<52;i++)
ans[i]=ans[i-1]+ans[i-2];
}
int main()
{
init();
int t,a,b;
cin>>t;
while(t--)
{
scanf("%d%d",&a,&b);
cout<<ans[b-a+1]<<endl;

}
return 0;
}


HDU2045 不容易系列之(3)—— LELE的RPG难题:

题目大意:有一排n个方格,每个方格用红,粉,绿三种颜色之一涂,要求每两个相邻的方格不能同色,同时第一个方格和最后一个方格也不能同色,问你一共有多少种不同的涂法。

对于第i个方格来说,它的涂法f(i)取决于第i-1个方格的颜色和第1个方格的颜色,如果第i-1个方格的颜色和第一个方格不同色,那么第i个方格就只有一种涂法了,有f(i)=1*f(i-1);如果第i-1个方格和第一个方格同色,那么我们就不用考虑这一格了,同时第i个方格有2种不同的涂法,有f(i)=2*f(i-2);由加法原理我们就得出了递推公式:f(n)=f(n-1)+2*f(n-2);注意把f(1)=1,f(2)=f(3)=6初始化就行了,对于f(3)还是比较特殊的。

#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
long long f[51];
int n,i;
f[1]=3;
f[2]=6;
f[3]=6;
for(i=4;i<=50;i++)
f[i]=f[i-1]+2*f[i-2];
while(scanf("%d",&n)!=-1)
cout<<f
<<endl;
return 0;
}


HDU2046 骨牌铺方格:

#include <cstdio>
#include <iostream>
using namespace std;
long long ans[55];
void init()
{
ans[1]=1;
ans[2]=2;
for(int i=3;i<52;i++)
ans[i]=ans[i-1]+ans[i-2];
}
int main()
{
init();
int n;
while(scanf("%d",&n)!=-1)
cout<<ans
<<endl;
return 0;
}


HDU2047 阿牛的EOF牛肉串:

对于下一个字符,分两种情况考虑:

(1)是“O”,那么前一个字母肯定不是‘O’,方法数等于2乘上前n-2个的方法数,即f(n)=2*f(n-2);

(2)不是“O”,那么就有“E”和“F”这两种情况,再乘上前n-1个的方法数,即f(n)=2*f(n-1);

根据加法原理:f(n)=2*(f(n-1)+f(n-2));

#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
long long f[41];
int n,i;
f[1]=3;
f[2]=8;
for(i=3;i<=40;i++)
f[i]=2*(f[i-1]+f[i-2]);
while(scanf("%d",&n)!=-1)
cout<<f
<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: