HDU 2152 选课时间(题目已修改,注意读题) (母函数)
選課時間(題目已修改,注意讀題)
Time Limit: 1000/1000 MS (Java/Others)????Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2026????Accepted Submission(s): 1612
?
Input 輸入數據的第一行是一個數據T,表示有T組數據。 每組數據的第一行是兩個整數n(1 <= n <= 40),k(1 <= k <= 8)。 接著有k行,每行有兩個整數a(1 <= a <= 8),b(1 <= b <= 10),表示學分為a的課有b門。?
Output 對于每組輸入數據,輸出一個整數,表示學n個學分的組合數。?
Sample Input 2 2 2 1 2 2 1 40 8 1 1 2 2 3 2 4 2 5 8 6 9 7 6 8 8?
Sample Output 2 445?
Author xhd?
Source ACM程序設計期末考試_熱身賽(感謝 xhd & 8600)?
Recommend lcy現在以上面的第二種情況每種種類個數無限為例,給出模板:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #include <iostream> using namespace std; // Author: Tanky Woo // www.wutianqi.com const int _max = 10001; // c1是保存各項質量砝碼可以組合的數目 // c2是中間量,保存沒一次的情況 int c1[_max], c2[_max]; int main() { //int n,i,j,k;int nNum; // int i, j, k;while(cin >> nNum){for(i=0; i<=nNum; ++i) // ---- ①{c1[i] = 1;c2[i] = 0;}for(i=2; i<=nNum; ++i) // ----- ②{for(j=0; j<=nNum; ++j) // ----- ③for(k=0; k+j<=nNum; k+=i) // ---- ④{c2[j+k] += c1[j];}for(j=0; j<=nNum; ++j) // ---- ⑤{c1[j] = c2[j];c2[j] = 0;}}cout << c1[nNum] << endl;}return 0; } |
?
?
我們來解釋下上面標志的各個地方:(***********!!!重點!!!***********)
①? 、首先對c1初始化,由第一個表達式(1+x+x^2+..x^n)初始化,把質量從0到n的所有砝碼都初始化為1.
②? 、 i從2到n遍歷,這里i就是指第i個表達式,上面給出的第二種母函數關系式里,每一個括號括起來的就是一個表達式。
③、j 從0到n遍歷,這里j就是(前面i個表達式累乘的表達式)里第j個變量,(這里感謝一下seagg朋友給我指出的錯誤,大家可以看下留言處的討論)。如(1+x)(1+x^2)(1+x^3),j先指示的是1和x的系數,i=2執行完之后變為
(1+x+x^2+x^3)(1+x^3),這時候j應該指示的是合并后的第一個括號的四個變量的系數。
④ 、 k表示的是第j個指數,所以k每次增i(因為第i個表達式的增量是i)。
⑤? 、把c2的值賦給c1,而把c2初始化為0,因為c2每次是從一個表達式中開始的。
?
初學者請閱讀:http://www.wutianqi.com/?p=596
?
#include<iostream> #include<cstdio> #include<cstring>using namespace std;const int N=50;int c1[N],c2[N],score[10];int main(){//freopen("input.txt","r",stdin);int t,n,m;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);for(int i=0;i<N;i++){c1[i]=0;c2[i]=0;}memset(score,0,sizeof(score));int a,b;for(int i=1;i<=m;i++){scanf("%d%d",&a,&b);score[a]=b;}c1[0]=1;for(int i=1;i<=m;i++){for(int j=0;j<=n;j++)for(int k=0;k<=score[i] && j+k*i<=n;k++)c2[j+k*i]+=c1[j];for(int j=0;j<=n;j++){c1[j]=c2[j];c2[j]=0;}}printf("%d\n",c1[n]);}return 0; }?
總結
以上是生活随笔為你收集整理的HDU 2152 选课时间(题目已修改,注意读题) (母函数)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vs生成失败不报错
- 下一篇: HDU Starship Troope