前言
動態規劃真的不入腦啊。鴿了那麼久,現在把暴力題解放上來
看到這題立馬有種動態規劃的感覺,小測結束後得知可以用母函數(雖然我也不知道母函數是個啥)
但對中二狗來說,幹就完了,奧裏給!
現在當事人表示非常後悔,暴力解了近一個小時,反而更麻煩,我還不如學個dp回來做題
暴力超神!附偷過來的一張圖
題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=2079
題解思路
實話說本來還有點擔心超時,但轉眼就讓我下定決心用暴力的,還是因爲題目的數據。你瞧瞧!
數據挺小的(霧),時間複雜度也就是O(a^b)
說實話沒超時確實是奇蹟,這尼瑪就離譜,最大可能都到十的八次了
誰知道里面的數據是怎麼想的呢= =
然後我就想寫k個for循環,對,就是你想的那樣,i,j……一層層下來
但這時候出了點麻煩,我不知道k的值,所以我不知道要提前寫幾個for循環啊!!!!!
然後,我想了想,比起現學動態,還是繼續把這問題解決吧,上百度搜
搜到了這個
博文的內容就不放了,懶。掌握個思路就好了,明白了可以用遞歸,遞歸裏再安排個參數小於k就能實現指定次數的循環
然後,就可以用for循環遞歸暴力啦。
我在代碼里加了很多詳細註釋,應該很容易懂吧。。
AC代碼
#include<iostream>//輸入輸出流,類似於c語言的stdio.h
using namespace std;
int a[10],b[10],n,s,k;//提前聲明變量,因爲調用了遞歸函數
void digui(int t,int sum)//sum代表學分總數
{
for(int i=0;i<=b[t];i++)//i代表該學分課程的個數
//總共有b[t]個,但我可以取1個1學分,也可以取多個
//所以自然而然開個循環
{
sum += i*a[t]; //學分個數i乘以學分數,然後和目標n比
if(sum>n) //如果總學分超過了n
{
sum -= i*a[t];//超過了自然要減去有這個i的這種情況
continue;// 跳到下一個i繼續把下一種搞定
}
if(sum == n)s++;//如果相等了就+1種情況,s代表情況數
else if(t<k)digui(t+1,sum);//沒到次數就繼續往下一個走
sum -= i*a[t];/*所有有關這種情況的在上面的遞歸中已經
都搞定了,所以現在把sum里加上這種情況的都減去,然後
開始下一個i的循環 */
}
}
int main()
{
int T;cin>>T;//輸入組數
while(T--)
{
s=0;
cin>>n>>k;//輸入n與k
for(int i=1;i<=k;i++)
cin>>a[i]>>b[i]; //輸入學科與學分
digui(1,0);//從a[1]開始 sum是0這樣就可以層層疊上去
cout<<s<<endl;//輸出s與換行
}
}
還是那句話,當事人十分後悔,想暴力做也不是那麼容易的。