hdu 5366 The mook jong

hdu 5366 The mook jong


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


思路1:首先我们可以确定的是,因为每两个木人桩之间的地砖必须大于等于2个,所以木人桩的个数k需满足k+2*(k-1)<=n,即k<=(n+2)/3。然后我们来找砖数和木人桩之间的关系。
Eg:n=7,k=2时,因为2个木人桩之间的地砖数至少需要2个,那么我只需要先取出这2块地砖,那么就相当于剩下的5个地砖上放2个木人桩,即C(5,2)=10,然后再将取出的地砖放回去就是所求解,所以对应的木人桩数k,我们只需要加上C(n-2*(k-1),k)即可。

思路2:状态转移方程: 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。


#include 
#include 
#include 
#define N 70
using namespace std;
long long dp[N] = {0, 1, 2, 3};
void fun()
{
    for (int i = 4; i <= 60; i++)
    {
        dp[i] = dp[i - 1] + dp[i - 3] + 1;
    }
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("1.txt", "r", stdin);
#endif
    int n, ans, i, j;
    fun();
    while(~scanf("%d", &n))
    {
        ans = 0;
        cout << dp[n] << endl;
    }

    return 0;
}

你可能感兴趣的:(动态规划,杭电,杭电)