1. 程式人生 > >HDU 2152(母函式)

HDU 2152(母函式)

Problem Description

轉眼到了收穫的季節,由於有TT的專業指導,Lele獲得了大豐收。特別是水果,Lele一共種了N種水果,有蘋果,梨子,香蕉,西瓜……不但味道好吃,樣子更是好看。

於是,很多人們慕名而來,找Lele買水果。
甚至連大名鼎鼎的HDU ACM總教頭 lcy 也來了。lcy丟擲一打百元大鈔,"我要買由M個水果組成的水果拼盤,不過我有個小小的要求,對於每種水果,個數上我有限制,既不能少於某個特定值,也不能大於某個特定值。而且我不要兩份一樣的拼盤。你隨意搭配,你能組出多少種不同的方案,我就買多少份!"
現在就請你幫幫Lele,幫他算一算到底能夠賣出多少份水果拼盤給lcy了。

注意,水果是以個為基本單位,不能夠再分。對於兩種方案,如果各種水果的數目都相同,則認為這兩種方案是相同的。最終Lele拿了這筆錢,又可以繼續他的學業了~

Input
本題目包含多組測試,請處理到檔案結束(EOF)。
每組測試第一行包括兩個正整數N和M(含義見題目描述,0<N,M<=100)
接下來有N行水果的資訊,每行兩個整數A,B(0<=A<=B<=100),表示至少要買該水果A個,至多隻能買該水果B個。

Output
對於每組測試,在一行裡輸出總共能夠賣的方案數。
題目資料保證這個答案小於10^9

Sample Input
2 3
1 2
1 2
3 5
0 3
0 3
0 3

Sample Output
2
12



Author
Linle

Source
ACM程式設計期末考試——2008-01-02

Solution

以下部分的版權歸本人(小飛)所有。所有權利保留。

歡迎轉載,轉載時請註明出處:

本題直接套用母函式模板即可。關於母函式的詳細解釋請看:

這裡順便演示一下,對於一般的題目,兩個模板都可以解決問題。

首先套用第一個模板。程式碼如下:


[cpp] view plain copy print?
  1. #include <iostream>
  2. #include <cstring>
  3. usingnamespace std;  
  4. #define min(a,b) ((a)<(b)?(a):(b))
  5. int N,M,n1[200],n2[200],i,j,k;  
  6. int a[200],b[200];  
  7. int main()  
  8. {  
  9.     while (cin>>N>>M)  
  10.     {  
  11.         for (i=0;i<N;i++)  
  12.             cin>>n1[i]>>n2[i];  
  13.         memset(a,0,sizeof(a));  
  14.         a[0]=1;  
  15.         for (i=0;i<N;i++)  
  16.         {  
  17.             memset(b,0,sizeof(b));  
  18.             for (j=n1[i];j<=n2[i]&&j<=M;j++)  
  19.                 for (k=0;k<=M&&k+j<=M;k++)  
  20.                     b[k+j]+=a[k];  
  21.             memcpy(a,b,sizeof(b));  
  22.         }  
  23.         cout<<a[M]<<endl;  
  24.     }  
  25.     return 0;  
  26. }  
#include <iostream>
#include <cstring>
using namespace std;
#define min(a,b) ((a)<(b)?(a):(b))
int N,M,n1[200],n2[200],i,j,k;
int a[200],b[200];
int main()
{
	while (cin>>N>>M)
	{
		for (i=0;i<N;i++)
			cin>>n1[i]>>n2[i];
		memset(a,0,sizeof(a));
		a[0]=1;
		for (i=0;i<N;i++)
		{
			memset(b,0,sizeof(b));
			for (j=n1[i];j<=n2[i]&&j<=M;j++)
				for (k=0;k<=M&&k+j<=M;k++)
					b[k+j]+=a[k];
			memcpy(a,b,sizeof(b));
		}
		cout<<a[M]<<endl;
	}
	return 0;
}

下來套用第二個模板。程式碼如下:
[cpp] view plain copy print?
  1. #include <iostream>
  2. #include <cstring>
  3. usingnamespace std;  
  4. #define min(a,b) ((a)<(b)?(a):(b))
  5. int N,M,n1[200],n2[200],i,j,k,last,last2;  
  6. int a[200],b[200];  
  7. int main()  
  8. {  
  9.     while (cin>>N>>M)  
  10.     {  
  11.         for (i=0;i<N;i++)  
  12.             cin>>n1[i]>>n2[i];  
  13.         a[0]=1;  
  14.         last=0;  
  15.         for (i=0;i<N;i++)  
  16.         {  
  17.             last2=min(last+n2[i],M);  
  18.             memset(b,0,sizeof(int)*(last2+1));  
  19.             for (j=n1[i];j<=n2[i]&&j<=last2;j++)  
  20.                 for (k=0;k<=last&&k+j<=last2;k++)  
  21.                     b[k+j]+=a[k];  
  22.             memcpy(a,b,sizeof(int)*(last2+1));  
  23.             last=last2;  
  24.         }  
  25.         if (last>=M)  
  26.             cout<<a[M]<<endl;  
  27.         else
  28.             cout<<0<<endl;  
  29.     }  
  30.     return 0;  
  31. }  
#include <iostream>
#include <cstring>
using namespace std;
#define min(a,b) ((a)<(b)?(a):(b))
int N,M,n1[200],n2[200],i,j,k,last,last2;
int a[200],b[200];
int main()
{
	while (cin>>N>>M)
	{
		for (i=0;i<N;i++)
			cin>>n1[i]>>n2[i];
		a[0]=1;
		last=0;
		for (i=0;i<N;i++)
		{
			last2=min(last+n2[i],M);
			memset(b,0,sizeof(int)*(last2+1));
			for (j=n1[i];j<=n2[i]&&j<=last2;j++)
				for (k=0;k<=last&&k+j<=last2;k++)
					b[k+j]+=a[k];
			memcpy(a,b,sizeof(int)*(last2+1));
			last=last2;
		}
		if (last>=M)
			cout<<a[M]<<endl;
		else
			cout<<0<<endl;
	}
	return 0;
}