CodeForces571A. Lengthening Sticks(組合數學-容斥)

題目大意:

a,b,c三根木棍能夠增長三個不一樣的數字,aa,bb,cc,且aa+bb+cc<=L,問能構成三角形的木棒有多少種方案c++

題目思路:

若是咱們直接考慮把L分配給aa,bb,cc好像很差下手ide

因此逆向考慮spa

合法的狀況  =  全部狀況 - 不合法的狀況.net

 

step1:

首先計算全部的狀況code

假設L當時爲lblog

咱們把長度爲l分配去的總的方案get

這個問題咱們等效爲:有三個籃子,每一個籃子放至少一個個物品,總共l個物品,問有多少種方案class


咱們用插板法解決這個問題sed

由於每一個籃子放至少一個,而咱們的目標是能夠放0個,怎麼辦呢?im

咱們能夠增長几個物品使初始每一個籃子中就有一個,這裏假設有m個籃子,n個物品

那咱們的物品個數變爲n+m,這時候會產生n+m-1個隔板

而後咱們要選出m部分來,也就是放m-1個隔板

此時的方案爲C(n+m-1,m-1)

 

回到這個題目

此時長度爲l時,方案爲C(l+3-1,3-1)

而後咱們枚舉一遍l,求和算出總的方案

因此獲得爲l的時候方案爲C(l+2,2)

step2:

求不合法的方案==

假設a+aa,b+bb,c+cc(aa,bb,cc分別爲分配的增長的長度)

假設a+aa是那條最長的邊

此時不合法須要知足以下條件:

b+bb+c+cc<=a+aa

bb+cc<=l-aa

bb+cc<=min(l-aa,a-b-c+aa)

令T=bb+cc

這個時候再進行一下問題轉化

有T個物品,分配到三個籃子裏(能夠分配0個)

三個籃子分別是bb,cc和多餘的部分

回到上面的插板法同樣的解法C(t+3-1.3-1)

而後用總的減去不合法就ok了

 CODE:

ll b,c,a,l;
int main() {
    a=read(),b=read(),c=read(),l=read();
    ll zong = (l+1)*(l+2)*(l+3)/6ll;
    ll no;
    for(int aa=0 ; aa<=l ; aa++) {
        ll t = min(l-aa,a-b-c+aa);
        if(t<0) continue;
        no = (t+2)*(t+1)/2ll;
        zong-=no;
    }
    for(int bb=0 ; bb<=l ; bb++) {
        ll t = min(l-bb,b-a-c+bb);
        if(t<0) continue;
        no = (t+2)*(t+1)/2ll;
        zong-=no;
    }
    for(int cc=0 ; cc<=l ; cc++) {
        ll t = min(l-cc,c-b-a+cc);
        if(t<0) continue;
        no = (t+2)*(t+1)/2ll;
        zong-=no;
    }
    out(zong);
    return 0;
}
View Code
相關文章
相關標籤/搜索