HDU 5366 The mook jong (动态规划,详解)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5366

题面:

The mook jong

Accepts: 221
Submissions: 306
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
Problem Description

ZJiaQ want to become a strong man, so he decided to play the mook jong。ZJiaQ want to put some mook jongs in his backyard. His backyard consist of n bricks that is 1*1,so it is 1*n。ZJiaQ want to put a mook jong in a brick. because of the hands of the mook jong, the distance of two mook jongs should be equal or more than 2 bricks. Now ZJiaQ want to know how many ways can ZJiaQ put mook jongs legally(at least one mook jong).

Input

There ar multiply cases. For each case, there is a single integer n( 1 < = n < = 60)

Output

Print the ways in a single line for each case.

Sample Input
1	
2
3
4
5
6
Sample Output
1
2
3
5
8
12


解题:
  一开始想推二维的dp,感觉会有重叠的情况,没推出来,后来找了个规律过了。
  看别人博客都写的很简单,我比较水,还是写详细点吧。
  状态转移方程: dp[i]=dp[i-1]+dp[i-3]+1。
  dp[i]的含义是到i这个位置为止,有多少种方案数,也就是答案。因为dp表示的是合法的解,所以之前一定已经至少放了一个木桩了。dp[i-1]代表的是当前位置i不放木桩,
dp[i-3]代表的是当前位置放,因为间隔为2,所以不论前面第三个位置有没有,当前位置i都可以放置1个木桩,至于最后加上的一个1,开始没怎么理解,其实它代表的是前面i-1
个位置都没放置木桩,而在当前位置i放置一个木桩,这也是一组合法的解,故加上1。
  虽然看上去dp方程那么简单,大家看看也就懂了,但是自己是否又真的能够快速得推出来呢?


代码:
#include   
#include 
#include 
using namespace std;
long long dp[65]={0,1,2,3};
void init()
{
  for(int i=4;i<=60;i++)
	  dp[i]=dp[i-1]+dp[i-3]+1;
}
int main()
{
	init();
	int n;
	while(~scanf("%d",&n))
	{
		printf("%lld\n",dp[n]);
	}
	return 0;
}


你可能感兴趣的:(编程题——动态规划)