您的位置:首页 > 其它

ACM: 简单 动态规划题 toj 1509 (…

2016-05-19 23:21 351 查看


                     
Worm

描述

自从见识了平安夜苹果的涨价后,Lele就在他家门口水平种了一排苹果树,共有N棵。

突然Lele发现在左起第P棵树上(从1开始计数)有一条毛毛虫。为了看到毛毛虫变蝴蝶的过程,Lele在苹果树旁观察了很久。虽然没有看到蝴蝶,但Lele发现了一个规律:每过1分钟,毛毛虫会随机从一棵树爬到相邻的一棵树上。

比如刚开始毛毛虫在第2棵树上,过1分钟后,毛毛虫可能会在第1棵树上或者第3棵树上。如果刚开始时毛毛虫在第1棵树上,过1分钟以后,毛毛虫一定会在第2棵树上。

现在告诉你苹果树的数目N,以及毛毛刚开始所在的位置P,请问,在M分钟后,毛毛虫到达第T棵树,一共有多少种行走方案数。

输入

本题目包含多组测试,请处理到文件结束(EOF)。

每组测试占一行,包括四个正整数N,P,M,T(含义见题目描述,0<N,P,M,T<100)

输出

对于每组数据,在一行里输出一共的方案数。

题目数据保证答案小于10^9

样例输入
3 2 4 2

3 2 3 2
 
样例输出
4

0

 
提示
[align=left]第一组测试中有以下四种走法:[/align]
2->1->2->1->2

2->1->2->3->2

2->3->2->1->2

2->3->2->3->2
[align=left] [/align]
[align=left]题意: 见题目 n:树的数目, p:起点, m:时间, t:终点.[/align]
[align=left] [/align]
[align=left]解题思路:[/align]
                
1. 这题有两种思维推导结果: 从前往后推导, 从后往前推导.
[align=left]                 从前往后推导:[/align]
                             
设 dp[i][j]: 前i分钟的时间,到达j树的走法总和.
                                   
dp[i][j] = dp[i-1][j+1] + dp[i-1][j-1];
(边界问题就是去掉一半即可.)
                             
显然结果是: dp[m][t];
                 
从后往前推导:
                             
设dp[i][j]: 从时间m往回退i分钟, 到达j树的走法总和.
                                     dp[i][j]
= dp[i+1][j+1] + dp[i+1][j-1];
                            
结果是: dp[1][p];
[align=left] [/align]
[align=left]递推代码:[/align]
#include
<cstdio>

#include <iostream>

#include <cstring>

using namespace std;

#define MAX 105
int n, m, p, t;

int dp[MAX][MAX];
int main()

{

// freopen("input.txt","r",stdin);

 while(scanf("%d %d %d
%d",&n,&p,&m,&t)
!= EOF)

 {

  memset(dp,0,sizeof(dp));

  dp[0][p] = 1;
  for(int i =
1; i <= m; ++i)

  {

   for(int j =
1; j <= n; ++j)

   {

    if(j
== 1) dp[i][j] = dp[i-1][j+1];

    else
if(j == n) dp[i][j] = dp[i-1][j-1];

    else
dp[i][j] = dp[i-1][j+1]+dp[i-1][j-1];

   }

  }

  printf("%d\n",dp[m][t]);

 }
 return 0;

}
[align=left] [/align]
[align=left]递归代码:[/align]
#include
<cstdio>

#include <iostream>

#include <cstring>

using namespace std;

#define MAX 105
int
n,p,m,t;

int dp[MAX][MAX];
int DP(int
i,int j)

{

 if(dp[i][j] != -1) return dp[i][j];

 if(i == 0)

 {

  if(j == p)

   return
dp[0][p];

  else

   return
0;

 }

 int ans;

 if(j == 1)

  ans = DP(i-1,j+1);

 else if(j == n)

  ans = DP(i-1,j-1);

 else

  ans =
DP(i-1,j-1)+DP(i-1,j+1);

 dp[i][j] = ans;

 return ans;

}
int
main()

{

// freopen("input.txt","r",stdin);

 while(scanf("%d %d %d
%d",&n,&p,&m,&t)
!= EOF)

 {

  memset(dp,-1,sizeof(dp));

  dp[0][p] = 1;

  int result =
DP(m,t);
  printf("%d\n",result);

 }
 return 0;

}
[align=left] [/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: