ACM--递推

1、递推入门第一题:习题:马踏过河卒
思路:开始第一想法就是直接搜索,但是会超时。但是注意到只能下与右时应该想到递推,因为对于任意一个点而言到他的方案数就是他左边与上边的方案数之和(因为对于这个点而言只能从左边或者上边到它)。

棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。
同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。
因此称之为“马拦过河卒”。 
棋盘用坐标表示,A点(0, 0)、B点(n, m)(n, m为不超过15的整数),同样马的位置坐标是需要给出的。
现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
 
Input
 
一行四个数据,分别表示B点坐标和马的坐标。(保证所有的数据有解)
 
Output
 
一个数据,表示所有的路径条数。
 
Sample Input
 
6 6 3 3
Sample Output
 
6
#include<iostream>
using namespace std;
long long map[25][25];
int b[8][2]={{1,-2},{-1,-2},{-2,-1},{2,-1},{-2,1},{2,1},{-1,2},{1,2}};
int n,m,cx,cy;
long long sum=0;
int main()
{
	cin>>n>>m>>cx>>cy;
	map[cx][cy]=-1;//不能忘记马自己本身所占的那个点
	for(int i=0;i<8;i++)//标记马控制点
	{
		int xx=cx+b[i][0];
		int yy=cy+b[i][1];
		if(xx>=0&&xx<=n&&yy>=0&&yy<=m)
			map[xx][yy]=-1;
	}
	map[0][0]=1;
	for(int i=0;i<=n;i++)
	{
		for(int j=0;j<=m;j++)
		{
			if(map[i][j]!=-1)
			{
				if(i>0&&map[i-1][j]!=-1)
					map[i][j]+=map[i-1][j];
				if(j>0&&map[i][j-1]!=-1)
					map[i][j]+=map[i][j-1];	
			}
		}
	}
	if(map[n][m]==-1)
		cout<<0<<endl;
	else
		cout<<map[n][m]<<endl;
	return 0;	
} 

2.递推入门第二题:墙壁涂色问题
思路:找递推式
当第n-1个和第1个同色时(当这种情况下,因为第n个与第1个和第n-1个不能同色,所以第n个就只有一种涂色方法)所以:p[n]=p[n-1]
当第n-1个和第1个不同色时(当这种情况下,因为第n个与第1个和第n-1个不能同色,同时第n-1个与第1个不同色。所以总的来说就是n-1和n是在与第一个不一样的两个颜色中二选一,一人一个。所以n-1与n两个的涂法只有两种)所以:p[n]=2p[n-2]
综上:p[n]=p[n-1]+2
p[n-2]

蒜头君觉得白色的墙面好单调,他决定给房间的墙面涂上颜色。他买了 3 种颜料分别是红、黄、蓝,然后把房间的墙壁竖直地划分成 n 个部分,蒜头希望每个相邻的部分颜色不能相同。他想知道一共有多少种给房间上色的方案。

例如,当 n = 5时,下面就是一种合法方案。
[外链图片转存失败(img-gOns3LTM-1564753415691)(https://res.jisuanke.com/img/upload/20170112/fd5e7a32a66daa37c6dbbac2b9a5dce8a1788b80.png)]
由于墙壁是一个环形,所以下面这个方案就是不合法的。
[外链图片转存失败(img-Y2AVaT36-1564753415692)(https://res.jisuanke.com/img/upload/20170112/c31b612f25e95eeabce3475540661d66a0e06495.png)]
输入格式
一个整数 n,表示房间被划分成多少部分。(1≤n≤50)

输出格式
一个整数,表示给墙壁涂色的合法方案数。
样例输入

4
样例输出

18

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    long long p[55]={0,3,6,6};
    for(int i=4;i<55;i++)
        p[i]=p[i-1]+p[i-2]*2;
    while(cin>>n)
        cout<<p[n]<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值