a,b,c三根木棍能夠增長三個不一樣的數字,aa,bb,cc,且aa+bb+cc<=L,問能構成三角形的木棒有多少種方案c++
若是咱們直接考慮把L分配給aa,bb,cc好像很差下手ide
因此逆向考慮spa
合法的狀況 = 全部狀況 - 不合法的狀況.net
首先計算全部的狀況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)
求不合法的方案==
假設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了
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; }