題目大意:
a,b,c三根木棍可以增加三個不同的數字,aa,bb,cc,且aa+bb+cc<=L,問能構成三角形的木棒有多少種方案
題目思路:
如果我們直接考慮把L分配給aa,bb,cc好像不好下手
所以逆向考慮
合法的情況 = 所有情況 - 不合法的情況
step1:
首先計算所有的情況
假設L當時為l
我們把長度為l分配去的總的方案
這個問題我們等效為:有三個籃子,每個籃子放至少一個個物品,總共l個物品,問有多少種方案
我們用插板法解決這個問題
因為每個籃子放至少一個,而我們的目標是可以放0個,怎麼辦呢?
我們可以增加幾個物品使初始每個籃子中就有一個,這裡假設有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; }