九度oj 1552 座位问题 DP

题目1552:座位问题

时间限制:1 秒

内存限制:128 兆

特殊判题:

提交:264

解决:73

题目描述:

计算机学院的男生和女生共n个人要坐成一排玩游戏,因为计算机的女生都非常害羞,男生又很主动,所以活动的组织者要求在任何时候,一个女生的左边或者右边至少有一个女生,即每个女生均不会只与男生相邻。现在活动的组织者想知道,共有多少种可选的座位方案。


例如当n为4时,共有
女女女女, 女女女男, 男女女女, 女女男男, 男女女男, 男男女女, 男男男男
7种。

输入:

输入包含多组测试用例,每组测试用例仅包含一个整数n(1<=n<=1000)。

输出:

对于每组测试用例,输出一个数代表可选的方案数,为防止答案过大,答案对1000000007取模。

样例输入:
1
2
4
样例输出:
1
2
7
昨天晚上就看着A题和D题明显动态规划,A题做了很久一直只过两个case,后来在网上看了看总算是明白了原理,接着做D题,就是这个题,这个题的难点很显然就是在不合法的队列后面添加人后可以组成合理的队列。我当时的思路是dp[i][0]表示第i个位置排男生的总方法数,dp[i][1]表示第i个位置排女生的总方法数,dp中存的方法数都是指的合法对列的个数,dp[i][0] = dp[i-1][0] + dp[i-1][1](在任意合法队列的后面放男孩就会成为以男孩结束的合法队列 ),但是dp[i][1]的状态当时一直想不到如何转移,就暂时放下了,去看另一种解题思路,在网上搜相关资料的时候发现了Min_lala(csdn博主)发的一篇博客,正好跟我的想法相同,但是他却很好的解决了我上面存在的dp[i][1]确定的难题,

dp[i][1] = sum(dp[k][0])(k = 0~i-2)
其实意思就是最后一个放女的那倒数第二个就一定也是女的但是男的最后一个放在那里呢,这个时候就要枚举所有最后一个男生出现的位置(其后边全放女生)

代码如下:

#include <cstdio>
#include <cmath>
#include <cstdlib>

const int maxx = 1001;
const int MOD = 1000000007;

int dp[maxx][2];

//0 boy 1 gril

void init(){
	int i,sum = 0;

	dp[0][0] = 1;
	dp[1][0] = 1;
	dp[1][1] = 0;
	for(i=2;i<1001;++i){
		dp[i][0] = dp[i-1][0]+dp[i-1][1];
		dp[i][0] %= MOD;
		sum += dp[i-2][0];//用来记录0—i-2位置处为最后一个男生时的合法队列数
		sum %= MOD;
		dp[i][1] = sum;
	}
}

int main(){
	int n,ans;

	init();

	while(scanf("%d",&n)!=EOF){
		ans = (dp[n][0] + dp[n][1])%MOD;
		printf("%d\n",ans);
	}
	return 0;
}





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