HDU4602 Partition (神奇的計算方式)
阿新 • • 發佈:2018-12-26
題目描述:
上述對正整數4的拆分中1出現了12次,現給出
,求對n的拆分中數字k出現的次數
多組資料,T<=10000
題目分析:
首先,對一個數n的所有拆分方案總共有
種,相當於在n相同的小球中插入p塊隔板(p=0,1,2…n-1),那麼總方案數為
由於k在同一個拆分中可能出現多次,不好處理,我們先考慮只計算一次的情況
-
n<k 輸出0
-
n=k 輸出1
-
n=k+1 輸出2
-
n>k+1
這時k倘若在靠左邊的位置,則右邊的數隨意拆分,數量為 ,k靠右同理
倘若k在中間,則有n-k-1個位置可選,設兩邊的數為t1,t2,則拆分方案數為
總的加起來就是 種但是,此時我們只求出了一個k的情況,同一種拆分中k出現多次怎麼辦?
其實思考一下,問題已經無意中解決了,若同一種拆分中有p個k,那麼這種拆分就會被統計到p次,因為我們並沒有管除了當前的k之外其他地方還會不會出現k,舉個例子:
這種拆分中,在 , , 時各統計了一次,係數問題已經解決了
總結一下,有些時候統計問題的去重操作其實很簡單,對稱的感覺很重要
比如這道題,看似會算重的統計方式實際上把次數也求出來了。
PS:要是在考場上,直接列表格:
很容易發現只跟n-k的大小有關
#include<cstdio>
const int mod = 1e9+7;
int ksm(int a,int b)
{
int s=1;
for(;b;b>>=1,a=1ll*a*a%mod) if(b&1) s=1ll*s*a%mod;
return s;
}
int main()
{
int T,n,k;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
if(n<k) puts("0");
else if(n<=k+1) printf("%d\n",n-k+1);
else printf("%d\n",1ll*(n-k+3)*ksm(2,n-k-2)%mod);
}
}