hdoj2563统计问题

统计问题

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5675    Accepted Submission(s): 3334


Problem Description
在一无限大的二维平面中,我们做如下假设:
1、  每次只能移动一格;
2、  不能向后走(假设你的目的地是“向上”,那么你可以向左走,可以向右走,也可以向上走,但是不可以向下走);
3、  走过的格子立即塌陷无法再走第二次;

求走n步不同的方案数(2种走法只要有一步不一样,即被认为是不同的方案)。
 

Input
首先给出一个正整数C,表示有C组测试数据
接下来的C行,每行包含一个整数n (n<=20),表示要走n步。
 

Output
请编程输出走n步的不同方案总数;
每组的输出占一行。
 

Sample Input
  
  
2 1 2
 

Sample Output
  
  
3 7
恩哒,考虑方案总数,果断用深搜,可惜,这一题深搜超时,由于数据少,可以打表过,也可以递推,当然递推不是我想出来的,我也还没有看明白
下面是深搜的代码
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

struct node
{
	int x, y, step;
};
int num, cnt;
int di[3][2] = {{-1, 0}, {0, -1}, {0, 1}};
int vis[50][50];
void dfs(int x, int y, int step)
{
	if(step == num)
	{
		cnt++;
		return ;
	}	
	int i, current_x, current_y;
	for(i = 0; i < 3; i++)
	{
		current_x = x + di[i][0];
		current_y = y + di[i][1];
		if(vis[current_x][current_y] == 0)
		{
			vis[current_x][current_y] = 1;
			dfs(current_x, current_y, step + 1);
			vis[current_x][current_y] = 0;
		} 
	}
}
int main()
{
	int n;
	scanf("%d", &n);
	while(n--)
	{
		cnt = 0;
		scanf("%d", &num);
		vis[25][25] = 1;//最初由于没有标记出发点,一直error,真是个警告啊
		dfs(25, 25, 0);
		printf("%d\n", cnt);
		memset(vis, 0, sizeof(vis));
	}
	return 0;
} 
//下面是打表的代码
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int ans[21] = {0,3,7,17,41,99,239,577,1393,3363,8119,19601,47321,114243,275807,665857,1607521,3880899,9369319,22619537,54608393};
int main()
{
	int n, num;
	scanf("%d", &n);
	while(n--)
	{
		scanf("%d", &num);
		printf("%d\n", ans[num]);
	}
	return 0;
}

//下面是递推的代码

设f[n]表示走n步的情况,话说最后一步可能由三种走法,向上,向左或向右,而无论倒数第二步怎么走,最后一步都能向上,所以最后一步向上的走法为f[n-1];
当最后一步向左或向右时要考虑第n-1步,如果第n-1步向上(方案为f[n-2】)则,第n步向左或向右的方案为2*f[n-2],如果第n-1步不向上(方案为f[n-1]-f[n-2]),则最后一步向左或向右的情况为f[n-1]-f[n-2];


#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int main()
{
	int n, i, num;
	scanf("%d", &n);
	int f[25];
	f[0] = 0;
	f[1] = 3;
	f[2] = 7;
	for(i = 3; i <= 20; i++)
	{
		f[i] = 2 * f[i - 1] + f[i - 2];
	}
	while(n--)
	{
		scanf("%d", &num);
		printf("%d\n", f[num]);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值