做题感受:是一道很好的母函数题,通过这题让我对母函数有了更加深刻的认识和理解。那几个for循环我感觉就是在打表,把所有情况都算出来,最后再选取有用的部分。解析见注释部分。
选课时间(题目已修改,注意读题)
每组数据的第一行是两个整数n(1 <= n <= 40),k(1 <= k <= 8)。
接着有k行,每行有两个整数a(1 <= a <= 8),b(1 <= b <= 10),表示学分为a的课有b门。
#include<stdio.h>
#include<string.h>
int c1[100],c2[100];
int arr[100];
int main()
{
int s,n,k;
int i,j;
int a,b,p;
scanf("%d",&s);
while(s--)
{
scanf("%d%d",&n,&k);
memset(c2,0,sizeof(c2));
memset(c1,0,sizeof(c1));
for(i=0;i<k;i++)
{
scanf("%d%d",&a,&b);
arr[a]=b;// 用我自己的话说就是把用来度量东西的砝码的单位质量 和 个数 用一个数组存起来
}
for(i=0;i<=arr[1];i++)//第一个括号里面的项数
//以前那个是n,现在的是arr[1],因为以前的砝码的个数是没有限制的,但现在是有限制的
//(1 + x + x^2 + ... ) 第一个括号一共有arr[1]个这样的数
c1[i]=1;
for(i=2;i<=8;i++)//有多少个括号,本题为8个括号 ,因为有8种学分,故有8个括号
// 有时不知道多少个括号,写学分数40个也可以
{
for(j=0;j<=40;j++)
for(k=0,p=0;p<=arr[i]&&k+j<=40;k+=i,p++)//p是保证有b门课,在寻找满足40的条件下,
// 也要不超过b门课的题目要求
c2[k+j] += c1[j];
for(j=0;j<=40;j++)
{
c1[j]=c2[j];
c2[j]=0;
}
}
printf("%d\n",c1[n]);
}
return 0;
}