燈的排列問題

2021-05-26 22:56:18 字數 2620 閱讀 7399

【1995提高】燈的排列問題

time limit:1000ms  memory limit:65536k

total submit:731 accepted:366

description

設在一排上有n個格仔(n≤20),若在格仔中放置有不同顏色的燈,每種燈的個數記為n1,n2,……nk(k表示不同顏色燈的個數)。(顏色數<4)

放燈時要遵守下列規則:

①同一種顏色的燈不能分開;

②不同顏色的燈之間至少要有乙個空位置。

例如:n=8(格仔數)

r=2(紅燈數)

b=3(藍燈數)

放置的方法有: r-b順序,b-r順序, 放置的總數為12種。

程式要求:求出排列方案總數。

input

資料輸入的方式為:

np1(顏色,為乙個字母) n1(燈的數量)

p2 n2

……q(結束標記,q本身不是燈的顏色)

output

排列方案總數

sample input

8

r 2b 3

q

sample output

12

source

ymh【解析】

這個題開始想的很複雜,想要一下子出解。

先簡化題目:相同顏色的燈必須放在一起,不同顏色的燈之間必須至少空乙個格仔,求排列總數。因為相同的燈必須放在一起,那麼可以把每種燈都看做只有乙個,將剩餘部分從總格仔數裡面減掉。這樣就可以看做是將m個不同顏色的燈放入n個格仔裡,要求任意兩個燈不可相鄰,求排列數。

本題的資料很弱,n<=20,顏色數<4。因此這樣思考,先不考慮燈的顏色,只要求每個燈不相鄰。可以用簡單的搜尋得出方案數,將這個方案數乘以顏色數的全排列數,即為本題答案。

我在想,如果本題的資料規模很大,搜尋加上剪枝也會超時的話,有沒有其他的方法來算。

可以這麼來做,依然是先不考慮燈的顏色,把所有的燈先放成一排,然後往裡「插空」。插空的時候要求燈和燈之間必須至少有乙個空,而最左端和最右端可以沒有空。

設最左端至最右端插的空數分別為 x1,x2,x3......xm+1,其中x1,xm+1>=0,x2,x3...xm>0(由x均為整數可知x2,x3...xm>=1);

令y1=x1,y2=x2-1,y3=x3-1...ym=xm-1,ym+1=xm+1,其中 y1,y2...ym+1>=0;

由x1+x2+...+xm+1=n-m 可得 y1+y2+...ym+1=n-m+m-1=n-1;

這樣一來,問題就轉化為求不定方程非負整數解的個數的問題,根據組合數學的相關知識,可以知道解的個數為c(n-1+m+1-1,m+1-1),即 c(n+m-1,m)。

知道這個以後,再乘以顏色數的全排列,即為答案了。

注意,算組合數的時候,應用分解質因數的方法,把分母約掉,將分子上的因數乘起來即可。

我只寫了第一種,搜尋也未加任何優化,這樣也是0ms過掉的,可見資料之弱。

程式如下:

var

a:array[1..53] of longint;

n,count,t,k,i:longint;

ans:int64;

s,c:string;

procedure try(l,x:longint);

var i:longint;

begin

if l=count then

begin

inc(ans);

exit;

end;

for i:=x+2 to n do

try(l+1,i);

end;

function fact(key:longint):int64;

var i:longint;

begin

fact:=1;

for i:=2 to key do

fact:=fact*i;

end;

begin

readln(n);

while true do

begin

readln(s);

if s='q' then break;

c:=copy(s,1,pos(' ',s)-1);

t:=ord(c[1])-ord('a')+1;

delete(s,1,pos(' ',s));

val(s,k);

inc(a[t],k);

inc(count);

end;

for i:=1 to 53 do

begin

dec(a[i]);

if a[i]>0 then

dec(n,a[i]);

end;

ans:=0;

for i:=1 to n do

try(1,i);

ans:=ans*fact(count);

writeln(ans);

end.

排列的問題

今天上離散數學,幾道有意思的題整理了下。1.5個0 6個1,排列有多少種 思路 不用去考慮1怎麼排,想象現在有11個位置,在這11個位置裡面選出5個填0就可以了,剩下的位置填1即可。所以答案就是11選5的排列,也可想到成 在 0 0 0 0 0 中插入6個1進行劃分。2.那現在有1元,2元,5元,1...

2032 燈的開關問題

time limit 20 second memory limit 20 mb 問題描述有n盞燈放在一排,從1到n依次編號,有n個人也從1到n依次編號,第乙個人將燈全部開啟,第二個人將凡是2的倍數的燈全部關閉,第三個人將凡是3的倍數的燈作相反處理,第4 5 n個人都把自己編號的倍數的燈作相反處理。問...

2032 燈的開關問題

time limit 20 second memory limit 20 mb 問題描述有n盞燈放在一排,從1到n依次編號,有n個人也從1到n依次編號,第乙個人將燈全部開啟,第二個人將凡是2的倍數的燈全部關閉,第三個人將凡是3的倍數的燈作相反處理,第4 5 n個人都把自己編號的倍數的燈作相反處理。問...