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


    题目描述

    设在一排上有N个格子(N≤20),若在格子中放置有不同颜色的灯,每种灯的个数记为N1,N2,……Nk(k表示不同颜色灯的个数)。
       放灯时要遵守下列规则:
    ①同一种颜色的灯不能分开;
    ②不同颜色的灯之间至少要有一个空位置。
     例如:

    N=8(格子数)
    R=2(红灯数)

    B=3(蓝灯数)

       放置的方法有:
          R-B顺序


          B-R顺序



        放置的总数为12种。
        程序要求:求排列总数。

    输入格式


    数据输入的方式为:
    N
    P1(颜色,为一个字母) N1(灯的数量)
    P2 N2
    ……
    Q(结束标记,Q本身不是灯的颜色)

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


    输出

    输出排列总数。
    样例输入
    8
    R 2
    B 3
    Q

    样例输出
    12


    题解: 

    记录方案的dfs:http://www.cnblogs.com/qscqesze/p/4334157.html
    注意同一颜色归到一起
    dfs出一种颜色顺序下的所有顺序
    再将它乘上N种颜色的排列数N!
    即可得到总排列数。。。。
    代码:
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 #define mem(a) memset(a,0,sizeof(a))
     5 #define mp(x,y) make_pair(x,y)
     6 const int INF = 0x3f3f3f3f;
     7 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
     8 inline ll read(){
     9     ll x=0,f=1;char ch=getchar();
    10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    12     return x*f;
    13 }
    14 //////////////////////////////////////////////////////////////////////////
    15 const int maxn = 1e5+10;
    16 
    17 int n,s,num,k;
    18 char c;
    19 struct node{
    20     char x;
    21     int y;
    22 }q[maxn];
    23 
    24 void dfs(int a,int b,int c){   //a表示已用颜色  b表示已放格子数  c表示是否要放空格  
    25     if(a==num && b==n){
    26         k++;  //同一颜色顺序下排序数  
    27         return ;
    28     }
    29     if(b > n) return ;
    30     if(!c) dfs(a+1,b+q[a].y,1);
    31     dfs(a,b+1,0);
    32 }
    33 
    34 int main(){
    35     n = read();
    36     while(cin>>c, c!='Q'){
    37         int b = read();
    38         s += b;
    39         bool f = 0;
    40         for(int i=0; i<num; i++){
    41             if(q[i].x == c){
    42                 q[i].y += b;
    43                 f = 1;
    44             }
    45         }
    46         if(!f){
    47             q[num].x = c;
    48             q[num++].y += b;
    49         }
    50     }
    51     int per=1;
    52     for(int i=1; i<=num; i++)
    53         per = per*i;
    54     if(n - (s+num-1) <= 0) {  //格子不够 
    55         puts("0");
    56         return 0;
    57     }else{
    58         dfs(0,0,0);
    59         cout << per*k << endl;
    60     }
    61 
    62     return 0;
    63 }
  • 相关阅读:
    Windows 命令行
    建议博客园提供 BT 资源发布功能——由分享 VS2005 Beta2 的历程想到的
    成功 自信 快乐(转载)
    轻松一下,加菲猫语录
    COmega 概述
    对 RBAC 几种模型的理解及初步实现构想
    DHTML 中滚动条的设置
    求婚
    终于有了自己的blog!
    VS2005 已发布!
  • 原文地址:https://www.cnblogs.com/yxg123123/p/6827696.html
Copyright © 2020-2023  润新知