【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
8r 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個人都把自己編號的倍數的燈作相反處理。問...