一本通 递推专栏

A 走楼梯(stairs)

【问题描述】

楼梯有N级台阶,上楼可以一步上一阶,也可以一步上二阶。编一递归程序,计算共有多少种不同走法?

【输入形式】

楼梯的N级台阶。

【输出形式】

输出走法数量。
【样例输入】

3
【样例输出】

3

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<queue> 
# include<map>
# include<string>
# include<cstring> 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII; 
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846; 

int n,f[MAX];

int main(){  
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    f[1] = 1; f[2] = 2;
    for(int i = 3; i <= n ; i++)
     f[i] = f[i - 1] + f[i - 2];
    cout<<f[n];
	return 0;
}

B 兔子繁殖(rabbit)

【问题描述】

有一种兔子,出生后一个月就可以长大,然后再过一个月一对长大的兔子就可以生育一对小兔子且以后每个月都能生育一对。现在,我们有一对刚出生的这种兔子,那么,n个月过后,我们会有多少对兔子呢?假设所有的兔子都不会死亡。

【输入形式】

输入文件仅一行,包含一个自然数n。

【输出形式】

输出文件仅一行,包含一个自然数,即n个月后兔子的对数。

【样例输入】

5
【样例输出】

5

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<queue> 
# include<map>
# include<string>
# include<cstring> 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII; 
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846; 

int n,f[MAX];

int main(){  
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    f[1] = 1; f[2] = 1;
    for(int i = 3; i <= n ; i++)
     f[i] = f[i - 1] + f[i - 2];
    cout<<f[n];
	return 0;
}

C 平面分割(surface)

【问题描述】

同一平面内有n(n≤500)条直线,已知其中p(p≥2)条直线相交于同一点,则这n条直线最多能将平面分割成多少个不同的区域?

【输入形式】

两个整数n(n≤500)和p(2≤p≤n)。

【输出形式】

一个正整数,代表最多分割成的区域数目。

【样例输入】

12 5

【样例输出】

73

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<queue> 
# include<map>
# include<string>
# include<cstring> 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII; 
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846; 

int n,m,ans;

int main(){  
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m;
    ans = 2 * m;
    for(int i = m + 1; i <= n ; i++)
     ans += i;
    cout<<ans;
	return 0;
}

D 骨牌铺法(domino)

【问题描述】

有1×n的一个长方形,用一个1×1、1×2和1×3的骨牌铺满方格。例如当n=3时为1×3的方格。此时用1×1、1×2和1×3的骨牌铺满方格,共有四种铺法。如下图:

在这里插入图片描述

【输入形式】

n
【输出形式】

铺法总数

【样例输入】

3
【样例输出】

4


#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<queue> 
# include<map>
# include<string>
# include<cstring> 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII; 
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846; 

int n,m,ans,f[MAX];

int main(){  
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    f[1] = 1 ; f[2] = 2;
    f[3] = 4;
    for(int i = 4 ; i <= n ; i++ )
     f[i] = f[i-1] + f[i - 2] + f[i - 3];
    cout<<f[n];
	return 0;
}

E 蜜蜂路线(bee)

【问题描述】

一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你:蜜蜂从蜂房M开始爬到蜂房N,M<N,有多少种爬行路线?

在这里插入图片描述

【输入形式】

输入M,N的值。

【输出形式】

爬行有多少种路线。

【样例输入】

1 14

【样例输出】

377


#include<bits/stdc++.h>
using namespace std;
int m,n;
vector<int>dp[1100];
 
 vector<int> add(vector<int> &A, vector<int> &B)
{
    if (A.size() < B.size()) return add(B, A);

    vector<int> C;
    int t = 0;
    for (int i = 0; i < A.size(); i ++ )
    {
        t += A[i];
        if (i < B.size()) t += B[i];
        C.push_back(t % 10);
        t /= 10;
    }

    if (t) C.push_back(t);
    return C;
}


int main()
{
    cin>>n>>m;;
    dp[1].push_back(1); 
    dp[2].push_back(1); 
    for(int i = 3;i<=m-n+1;i++)
    {
        dp[i]=add(dp[i-1],dp[i-2]);
    }
    for(int i = dp[m-n+1].size() -1 ; i >= 0 ; i--)
    cout<<dp[m-n+1][i];
    return 0;
}

F 数塔问题

【问题描述】

有形如图所示的数塔,从顶部出发,在每个节点可以选择向左走或是向右走,一起走到底层,要求找出一条路径,使路径上的值最大。

在这里插入图片描述

【输入形式】
第1行,输入,n(表示数塔层数),接下来共n行,每一行为该层数塔的初始值

【输出形式】

1行,输出路径上的最大值


#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<queue> 
# include<map>
# include<string>
# include<cstring> 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII; 
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846; 

int n,a[1005][1005];

int main(){  
   std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for(int i = 1 ; i <= n ; i++ )
     for(int j = 1 ; j <= i ; j++)
      cin >> a[i][j];
    
	for(int i = n - 1 ; i >= 1; i -- )
	 for(int j = 1 ; j <= i ; j ++ )
	  a[i][j] = a[i][j] + max(a[i+1][j],a[i+1][j+1]);
	cout<<a[1][1];
	return 0;
}

G 昆虫繁殖

【问题描述】

科学家在热带森林中发现了一种特殊的昆虫,这种昆虫的繁殖能力很强。每对成虫过x个月产y对卵,每对卵要过两个月长成成虫。假设每个成虫不死,第一个月只有一对成虫,且卵长成成虫后的第一个月不产卵(过X个月产卵),问过Z个月以后,共有成虫多少对?0≤X≤20,1≤Y≤20,X≤Z≤50。

【输入形式】

x,y,z的数值。

【输出形式】

过Z个月以后,共有成虫对数。

【样例输入】

1 2 8

【样例输出】

37


#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<queue> 
# include<map>
# include<string>
# include<cstring> 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII; 
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846; 

ll f[MAX],s[MAX];
int x,y,z;

int main(){  
   std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> x >> y >> z;
    f[1] = 1;
   for(int i = 2 ; i <= z + 1 ; i++){
    	 f[i] = f[i - 1] + s[i - 2];
    	 if (i >= x) s[i] = f[i - x] * y;
	}
	

	cout<<f[z+1];
	return 0;
}

H 位数问题

【问题描述】

在所有的n位数中,有多少个数中有偶数个数字3?由于结果可能很大,你只需要输出这个答案对12345取余的值。

【输入形式】

读入一个数n

【输出形式】

输出有多少个数中有偶数个数字3

【样例输入】

2
【样例输出】

73


#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<queue> 
# include<map>
# include<string>
# include<cstring> 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII; 
const int mod=12345;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846; 

ll a[1005],b[1005],n;

int main(){  
   std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n;
   if(n==1) {
   	cout<<9;
   	return 0;
   }
   a[1] = 9 ; b[1] = 1; 
  for(int i = 2 ; i < n ; i ++){
  	 a[i] = (a[i - 1] * 9 + b[i - 1]) % mod;
  	 b[i] = (b[i - 1] * 9 + a[i - 1]) % mod;
  } 
  
  cout<<(a[n - 1] * 8 + b[n - 1]) % mod;
	
	return 0;
}

J 过河卒(Noip2002)

【问题描述】

棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上的某一点有一个对方的马(如C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点,如图3-1中的C点和P1,……,P8,卒不能通过对方马的控制点。棋盘用坐标表示,A点(0,0)、B点(n, m) (n,m为不超过20的整数),同样马的位置坐标是需要给出的,C≠A且C≠B。现在要求你计算出卒从A点能够到达B点的路径的条数。

在这里插入图片描述

【输入形式】

B点的坐标(n,m)以及对方马的坐标(X,Y)。

【输出形式】

一个整数(路径的条数)。从A点能够到达B点的路径的条数。

【样例输入】

6 6 3 2

【样例输出】

17


#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<queue> 
# include<map>
# include<string>
# include<cstring> 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII; 
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846; 

int dx[9] = {0, -2, -1, 1, 2, 2, 1, -1, -2};
int dy[9] = {0, 1, 2, 2, 1, -1, -2, -2, -1};
ll a[105][105];
int vis[105][105];
int n,m,x,y;

int main(){  
   std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m >> x >> y;
    n += 2; m += 2; x += 2 ; y += 2;
    a[2][2] = 1;
    
    for(int i = 0 ; i < 9 ; i ++ )
     vis[x + dx[i]][y + dy[i]] = 1;
     
     for(int i = 2 ; i <= n; i ++ ){
        for(int j = 2;j <= m;j ++){
          if(vis[i][j])continue;
            a[i][j]=max(a[i][j],a[i-1][j]+a[i][j-1]); 
        }
    }
    cout<<a[n][m];
	return 0;
}

K 邮票问题

【问题描述】

设有已知面额的邮票m种,每种有n张,用总数不超过n张的邮票,能从面额1开始,最多连续组成多少面额?(1<=m<=100,1<=n<=100,1<=邮票面额<=255)

【输入形式】

第一行:m,n的值,中间用一空格隔开

第二行:a[1,m](面额),每个数中间用一空格隔开

【输出形式】

连续面额数的最大值

【样例输入】

3 4

1 2 4

【样例输出】

14


#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<queue> 
# include<map>
# include<string>
# include<cstring> 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII; 
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846; 

int m,n,a[MAX],t,s,maxn;
int dp[MAX];

int main(){  
   std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> m >> n;
    for(int i = 0 ; i < m ; i ++ )
     cin >> a[i] , maxn = a[i];
     memset(dp,0x3f,sizeof dp);
	 dp[0] = 0 ;
	 
	 for(int i = 1 ; i <= maxn * n ; i++ ){
	 	
	 	 for(int j  = 0 ; j < m ; j ++ )
	 	  if(i >= a[j])
	 	    dp[i] = min(dp[i],dp[i - a[j]] + 1);

	    if(dp[i] > n || dp[i] == 0x3f){
	    	 cout<< i -1 ;
	    	 return 0;
		} 
	 }  
     
  
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值