有排成一行的n个方格,用红(Red)、粉(Pink)、绿(Green)三色涂每个格子,每格涂一色,要求任何相邻的方格不能同色,且首尾两格也不同色.求全部的满足要求的涂法.
以上就是著名的RPG难题.
如果你是Cole,我想你一定会想尽办法帮助LELE解决这个问题的;如果不是,看在众多漂亮的痛不欲生的Cole女的面子上,你也不会袖手旁观吧?
本题目需要分情况讨论,需要考虑倒数第二个的颜色情况,代码如下
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
int main(){
int n;
while(scanf("%d",&n)!=EOF){
long long a[51];
memset(a,0,sizeof(a));
a[1]=3;
a[2]=6;
a[3]=6;
if(n==1) printf("%lld\n",a[1]);
if(n==2) printf("%lld\n",a[2]);
if(n==3) printf("%lld\n",a[3]);
if(n>=4){
for(int i=4;i<=n;i++){
a[i]=2*a[i-2]+a[i-1];
}
printf("%lld\n",a[n]);
}
}
return 0;
}
首先,给每位新娘打扮得几乎一模一样,并盖上大大的红盖头随机坐成一排;
然后,让各位新郎寻找自己的新娘.每人只准找一个,并且不允许多人找一个.
最后,揭开盖头,如果找错了对象就要当众跪搓衣板...
看来做新郎也不是容易的事情...
假设一共有N对新婚夫妇,其中有M个新郎找错了新娘,求发生这种情况一共有多少种可能.
这是一个完全错排加组合数的题目,即部分错排,代码如下
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
#define ull unsigned long long
int extract(int n,int m){
ull sum=1,sum1=1;
ull ans;
for(int i=n;i>=n-m+1;i--){
sum*=i;
}
for(int i=m;i>=1;i--){
sum1*=i;
}
ans=sum/sum1;
return ans;
}
int main(){
int c;
int n,m;
scanf("%d",&c);
while(scanf("%d%d",&n,&m)!=EOF){
c--;
ull a[21];
ull ans=1;
memset(a,0,sizeof(a));
a[1]=1;
a[2]=2;
if(m==2) cout<<a[1]*extract(n,m)<<endl;
if(m==3) cout<<a[2]*extract(n,m)<<endl;
if(m>=4){
for(int i=3;i<=m-1;i++){
a[i]=i*(a[i-1]+a[i-2]);
}
ans=extract(n,m)*a[m-1];
cout<<ans<<endl;
}
if(c<1) break;
}
return 0;
}
这是一个部分错排累加的题目,需要注意的是可以错答(0~n/2),代码如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef unsigned long long ll;
ll a[31];
ll jiecheng(int m,int n){
ll sum1=1;
if(n==0) return 1;
else{
for(int i=1;i<=n;i++){
sum1*=m-i+1;
sum1/=i;
}
return sum1;
}
}
int main(){
memset(a,0,sizeof(a));
a[1]=0;
a[2]=1;
for(int i=3;i<=30;i++){
a[i]=(i-1)*(a[i-1]+a[i-2]);
}
int n;
while(scanf("%d",&n)!=EOF){
ll ans=1;
if(n==0) continue;
for(int i=1;i<=n/2;i++){
ans+=a[i]*jiecheng(n,i);
}
cout<<ans<<endl;
}
return 0;
}
总结:这类题目要着重分析,注意分情况讨论,要看清题意
错排公式为D(n)=(n-1)*((D(n-1)+D(n-2));
此类题通常会和组合数并用,求组合数要注意技巧避免爆栈,可用以下技巧:
ll jiecheng(int m,int n){
ll sum1=1;
if(n==0) return 1;
else{
for(int i=1;i<=n;i++){
sum1*=m-i+1;
sum1/=i;
}
return sum1;
}
}