题目链接: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 <stdio.h> #include <iostream> #include <cstring> 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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。