noip 1995 灯的排列问题 排列组合 DFS

题目描述

设在一排上有N个格子(N≤20),若在格子中放置有不同颜色的灯,每种灯的个数记为N1,N2,……Nk(k表示不同颜色灯的个数)。

   放灯时要遵守下列规则:

①同一种颜色的灯不能分开;

②不同颜色的灯之间至少要有一个空位置。

   例如:N=8(格子数)

         R=2(红灯数)

         B=3(蓝灯数)

   放置的方法有:

      R-B顺序

R

R

 

B

B

B

 

 

R

R

 

 

B

B

B

 

R

R

 

 

 

B

B

B

 

R

R

 

B

B

B

 

 

R

R

 

 

B

B

B

 

 

R

R

 

B

B

B

   

      B-R顺序

B

B

B

 

R

R

 

 

B

B

B

 

 

R

R

 

B

B

B

 

 

 

R

R

 

B

B

B

 

R

R

 

 

B

B

B

 

 

R

R

 

 

B

B

B

 

R

R

    放置的总数为12种。

    程序要求:求排列总数。

输入格式

数据输入的方式为:

N

P1(颜色,为一个字母) N1(灯的数量)

P2 N2

……

Q(结束标记,Q本身不是灯的颜色)

 颜色和灯的数量之间由一个空格分隔。

输出

输出排列总数。

样例输入

8
R 2
B 3
Q

样例输出

12

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
struct color{    
   char aa;
   int bb;
}q[10];
struct node
{
    char x;
    int y;
}miss[30];
int num=0,s;
int sss=0;     
vector<int> qq[1000];
vector<int> m;
int kiss=0;
void dfs(int a,int b,int c)          
{
    if(a==num&&b==s)
    {
        sss++;
        //cout<<m.size()<<endl;
        for(int i=0;i<m.size();i++)
        {
            qq[kiss].push_back(m[i]);
        }
        kiss++;
        for(int i=0;i<m.size();i++)
        {
            cout<<qq[kiss-1][i];
        }
        cout<<endl;
        return;
    }
    if(b>s)
        return;
    if(c!=1)
    {
        m.push_back(1);
        dfs(a+1,b+q[a].bb,1);
        m.pop_back();
    }
    m.push_back(0);
    dfs(a,b+1,0);
    m.pop_back();

}
int main()
{
    kiss=0;
    int i,j;
    int sum;
    int ss=0;
    char a;
    int b;
    scanf("%d",&s);
    int pp=0;
    while(cin>>a&&a!='Q')
    {
        miss[pp].x=a;
        scanf("%d",&b);
        miss[pp++].y=b;
        ss=ss+b;
        int t=0;
        for(i=0;i<num;i++)
        {
            if(q[i].aa==a)
            {
                q[i].bb+=b;
                t=1;
            }
        }
        if(t==0)
        {
            q[num].aa=a;
            q[num++].bb=b;
        }
    }
    int per=1;
    for(i=1;i<=num;i++)
        per=per*i;
    if(s-ss-num+1<=0)        
        cout<<0<<endl;
    else
    {
        dfs(0,0,0);
        /*
        cout<<"1"<<endl;
        for(int i=0;i<pp;i++)
            cout<<miss[i].x<<" "<<miss[i].y<<endl;
        */
        int a[10];
        for(int ii=0;ii<kiss;ii++)
        {
            for(int i=0;i<pp;i++)
                a[i]=i;
            int flag=0;
            for(int i=0;i<qq[ii].size();i++)
            {
                //cout<<"1";
                if(qq[ii][i]==0)
                    cout<<" ";
                else
                {
                    for(int j=0;j<miss[a[flag]].y;j++)
                        cout<<miss[a[flag]].x;
                    flag++;
                }
            }
            cout<<endl;

            while(next_permutation(a,a+pp))
            {
                flag=0;
                for(int i=0;i<qq[ii].size();i++)
                {
                    if(qq[ii][i]==0)
                        cout<<" ";
                    else
                    {
                        for(int j=0;j<miss[a[flag]].y;j++)
                            cout<<miss[a[flag]].x;
                        flag++;
                    }
                }
                cout<<endl;
            }
        }
        cout<<sss*per<<endl;
    }
    return 0;
}

 

posted @ 2015-03-13 01:21  qscqesze  阅读(829)  评论(0编辑  收藏  举报