参考:
http://blog.csdn.net/xiaofei_it/article/details/17042651
母函数与排列组合:
https://www.cnblogs.com/dolphin0520/archive/2012/11/07/2755080.html
// n1为最少数量数组,n2为最大数量数组,v为权值,p为最大值
//为计算结果,b为中间结果。
int a[MAX],b[MAX];
//初始化a
memset(a,0,sizeof(a));
a[0]=1;
for (int i=1;i<=17;i++)//循环每个因子
{
memset(b,0,sizeof(b));
for (int j=n1[i];j<=n2[i]&&j*v[i]<=P;j++)//循环每个因子的每一项
for (int k=0;k+j*v[i]<=P;k++)//循环a的每个项
b[k+j*v[i]]+=a[k];//把结果加到对应位, x^k * x^(j*v[i]) = x^(k+j*v[i])
memcpy(a,b,sizeof(b));//b赋值给a
}
//初始化a,因为有last,所以这里无需初始化其他位
a[0]=1;
int last=0;
for (int i=0;iint last2=min(last+n[i]*v[i],P);//计算下一次的last
memset(b,0,sizeof(int)*(last2+1));//只清空b[0..last2]
for (int j=n1[i];j<=n2[i]&&j*v[i]<=last2;j++)//这里是last2
for (int k=0;k<=last&&k+j*v[i]<=last2;k++)//这里一个是last,一个是last2
b[k+j*v[i]]+=a[k];
memcpy(a,b,sizeof(int)*(last2+1));//b赋值给a,只赋值0..last2
last=last2;//更新last
}
生成函数题集
https://blog.csdn.net/consciousman/article/details/77935700
一、hdu 1085和hdu 1171两题套用了第二个模板,省略了代码中二三层循环里关于last2的条件(其实也可以加上)。
详见:
hdu 1085:http://blog.csdn.net/xiaofei_it/article/details/17041467
hdu 1171:http://blog.csdn.net/xiaofei_it/article/details/17041709
二、hdu 1398套用了第一个模板,因为n2中每一项为无穷大,所以n2数组就省略了。
详见:
hdu 1398:http://blog.csdn.net/xiaofei_it/article/details/17041815
三、hdu 2079、hdu 2082和hdu 2110三题直接套用了第二个模板。
详见:
hdu 2079:http://blog.csdn.net/xiaofei_it/article/details/17042045
hdu 2082:http://blog.csdn.net/xiaofei_it/article/details/17042253
hdu 2110:http://blog.csdn.net/xiaofei_it/article/details/17042421
另外,至于什么时候用第一个模板,什么时候用第二个模板,就看题目规模。
通常情况下,第一个模板就够用了,上面的那些用第二个模板的题目用第一个模板同样能AC。
但如果数据规模比较大(通常不会有这种情况),就要使用第二个模板了。
以上题目n1均为0。
四、hdu 2152是一道n1不为0的题目,我在这里分别套用第一个和第二个模板解题。
详见:
hdu 2152:http://blog.csdn.net/xiaofei_it/article/details/17042497