0/1序列排列

题目描述
构建一个由0/1的组成的n个数序列,保证没有两个1相邻,问有多少这样的序列。
思路

  1. 这道题可以用组合的方式来做,首先枚举序列中1的个数(0~$ \left \lceil n/2 \right \rceil $ ),那么序列中0的个数就是n~ \(\left \lfloor n/2 \right \rfloor\) ,假设有i个1,就有n-i个0,将这些0排成一列,会得到n-i+1个空,要放入i个1,组合数\(C_{n-i+1}^{i}\),所有的就是\(\sum_{i=0}^{\left \lceil n/2 \right \rceil} C_{n-i+1}^{i}\)
#include<iostream>
using namespace std;
int n;
int f[20];
int main(){
	cin>>n;
	f[0]=1;
	for(int i=1;i<=n+1;i++){
		f[i]=f[i-1]*i;
	}
	int ans=0;
	for(int i=0;i<=(n+1)/2;i++){
		ans+=f[n-i+1]/(f[i]*f[n-i*2+1]);
	}
	cout<<ans;
	return 0;
}
  1. 这道题用组合的方法可能很难想,但是还有DP做法,\(f[i][j]\)表示i位序列最后一位是j时的这样的序列总数。转移方程为\(f[i][1]=f[i-1][0]\)\(f[i][0]=f[i-1][1]+f[i-1][0]\)
#include<iostream>
using namespace std;
int n;
int f[20][2];
int main(){
	cin>>n;
	f[1][1]=1;
	f[1][0]=1;
	for(int i=2;i<=n;i++){
		f[i][1]=f[i-1][0];
		f[i][0]=f[i-1][1]+f[i-1][0];
	}
	cout<<f[n][1]+f[n][0];
	return 0;
}
posted @ 2022-05-26 11:48  zzzzzz2  阅读(218)  评论(0)    收藏  举报