計蒜客:蒜頭君的新遊戲---DP

題目描述:

工作空閒之餘,蒜頭君經常帶着同事們做遊戲,最近蒜頭君發明了一個好玩的新遊戲:n 位同事圍成一個圈,同事 A 手裏拿着一個兔妮妮的娃娃。蒜頭君喊遊戲開始,每位手裏拿着娃娃的同事可以選擇將娃娃傳給左邊或者右邊的同學,當蒜頭君喊遊戲結束時,停止傳娃娃。此時手裏拿着娃娃的同事即是敗者。
玩了幾輪之後,蒜頭君想到一個問題:有多少種不同的方法,使得從同事 A 開始傳娃娃,傳了 m 次之後又回到了同事 A 手裏。兩種方法,如果接娃娃的同事不同,或者接娃娃的順序不同均視爲不同的方法。例如 1−>2−>3−>1 和 1−>3−>2−>1 是兩種不同的方法。
輸入格式
輸入一行,輸入兩個整數 n,m(3≤n≤30,1≤m≤30),表示一共有 n 位同事一起遊戲,一共傳 m 次娃娃。
輸出格式
輸出一行,輸出一個整數,表示一共有多少種不同的傳娃娃方法。
樣例輸入
3 3
樣例輸出
2

解題思路:
我們定義dp[i][j]爲傳了i次球,此刻球在第j個人的手上。
(1)dp數組的初始化:只傳一次球可以把球傳到第2個人和第n個人手上,且只有一個辦法。所以,dp[1][2]=1;dp[1][n]=1;
(2)狀態轉移方程爲:dp[i][j]=dp[i-1][j-1]+dp[i-1][j+1];(要注意第1個人和第n個人特殊一些,具體看代碼)

AC代碼:

#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
int dp[35][35];
int main()
{
	int n,m,i,j;
	cin>>n>>m;
//	dp[i][j]表示傳了i次球,現在球在第j個人手上 
	dp[1][2]=1;//這個步驟(dp數組的初始值)比較難想一些,傳一次只能把球傳到第2個人或者第n個人手上 
	dp[1][n]=1;
	for(i=1;i<=m;i++)
	{
		for(j=1;j<=n;j++)
		{
			if(j==1)
				dp[i][j]=dp[i-1][n]+dp[i-1][2];
			else if(j==n)
				dp[i][j]=dp[i-1][n-1]+dp[i-1][1];
			else
				dp[i][j]=dp[i-1][j-1]+dp[i-1][j+1];
		}
	}
	cout<<dp[m][1]<<endl;
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章