題面在這裡
有\(n\)種顏色的小球,每種顏色的小球有\(a_i\)個;
要把它們擺成一排,求相鄰小球顏色不相同的擺放方案數。
任意兩個合理的安排方法,只要有乙個位置的同學不同,都被認為是不同的。
\[n\le 50,a_i\le 50,\sum a_i\le 500
\]鳴謝ycb
以下先考慮可重排列的情況
考慮容斥:
\[ans=\sum_^(-1)^f(i)
\]其中\(f(x)\)表示至少有\(x\)對相鄰同色球的方案數。
直接求多項式\(f(x)\)不好求,我們先考慮一種顏色。
由於可重排列的方案數\(p=\frac\),
對於一種顏色的小球,構造多項式
\[g_i(x)=\sum_^(-1)^\frace(a_i,a_i-j)x^
\]其中\(e(i,j)\)表示把\(i\)個相同的小球分成\(j\)段的方案數,
相當於在\(i-1\)個空隙中選\(j-1\)塊隔板,因此\(e(i,j)=\binom\)。
於是$$f(x)=(\sum_^ a_i)\prod_^g_i(x)$$
直接暴力多項式乘法即可,複雜度為\(o(n(∑a_i)a_)\)
#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#define file "a"
#define mp make_pair
#define pb push_back
#define rg register
#define il inline
using namespace std;
typedef unsigned long long ull;
typedef vectorvi;
typedef long long ll;
typedef double dd;
const dd eps=1e-10;
const int mod=1e9+7;
const int n=505;
const dd pi=acos(-1);
il ll read()
il void file()
il void upd(int &a,int b)
il void dec(int &a,int b)
il int poww(int a,int b)
int fac[n],inv[n],c[n][n];
il void init()
}int t,n,x,f[n],g[n],h[n],sum,ans,tot;
int main()
memset(h,0,sizeof(h));
for(rg int j=0;jfor(rg int k=0;kupd(h[j+k],1ll*f[j]*g[k]%mod);
swap(f,h);
} for(rg int i=0;iupd(ans,1ll*f[i]*fac[sum-i]%mod);
printf("case %d: %lld\n",t,1ll*ans*tot%mod);
} return 0;
}
HDU 湫秋系列故事 安排座位 組和DP
題意 中文.思路 話說這類題目做的真的很少,比賽時無從下手。首先我們不考慮組內之間的順序問題,將其轉化為組合。dp i j 表示第i組插入到佇列中存在j個空,該空的左右兩邊是同一組的人,這樣我們只要將第i 1組的人查到該空的話,就是合法的。這裡用了一下滾動陣列優化了一下。dp cur i k x j...
HDU 湫秋系列故事 安排座位 組和DP
題意 中文.思路 話說這類題目做的真的很少,比賽時無從下手。首先我們不考慮組內之間的順序問題,將其轉化為組合。dp i j 表示第i組插入到佇列中存在j個空,該空的左右兩邊是同一組的人,這樣我們只要將第i 1組的人查到該空的話,就是合法的。這裡用了一下滾動陣列優化了一下。dp cur i k x j...
HDU4544 湫湫系列故事 消滅兔子
hdu 4544 tags 資料結構,貪心 analysis 將兔子的血量從大到小排序,將箭的殺傷力從大到小排序,對於每乙個兔子血量,將比他大的殺傷力大的劍壓入優先佇列,優先佇列自己重寫,讓它每次丟擲的數為價錢最小。code include include include include using...