hdu1028

来源:互联网 发布:数控编程员工资 编辑:程序博客网 时间:2024/06/05 21:17
 
概念:整数拆分:
所谓整数拆分即把整数分解成若干整数的和(相当于把n个无区别的球放到n个无标志的盒子,盒子允许空,也允许放多于一个球)。
整数拆分成若干整数的和,办法不一,不同拆分法的总数叫做拆分数。
 
链接网址: http://acm.hdu.edu.cn/showproblem.php?pid=1028
 
#include<iostream>#include<cstring>using namespace std;const int N=301;int n,a[N],b[N];void fun(int n){    int i,j,k;    memset(a,0,sizeof(a));    memset(b,0,sizeof(b));    for(i=0;i<=n;i++) a[i]=1; //先生成一个函数,实质为1+x+x^2+x^3+……x^n    for(i=2;i<=n;i++){       //生成其余的函数对应1+x^i+x^2i+……        for(j=0;j<=n;j++)            for(k=0;k+j<=n;k+=i)                b[j+k]+=a[j];            //二多项式相乘,先将第一个多项式逐项乘后一个多项式,            //如果二项相乘积大于x^n便可结束,道理如上一样,对最后结果无影响,            //为什么使用k+=i*i,其实质就是一个生成函数:1+x^(i*i)+x^2(i*i)+……,            //没有的项系数为0,对于有效的项刚累加a[j],            //不是加1的原因为可能a[]中不存在第j项,也就是说x^j的系数为0            for(k=0;k<=n;k++)//将结果保存在a[]中,将b[]清0,以便再循环使用            {   a[k]=b[k];b[k]=0;}    }        } int main(){    while(cin>>n && n)    {          fun(n);          cout<<a[n]<<endl;    } }

硬币合并问题:http://acm.hdu.edu.cn/showproblem.php?pid=1398
 
#include<iostream>#include<cstring>using namespace std;const int N=301;int n,a[N],b[N];void fun(int n){    int i,j,k;    memset(a,0,sizeof(a));    memset(b,0,sizeof(b));    for(i=0;i<=n;i++) a[i]=1; //先生成一个函数,实质为1+x+x^2+x^3+……x^n    for(i=2;i<=17;i++){       //生成其余的函数对应1+x^i+x^2i+……        for(j=0;j<=n;j++)            for(k=0;k+j<=n;k+=i*i)                b[j+k]+=a[j];            //二多项式相乘,先将第一个多项式逐项乘后一个多项式,            //如果二项相乘积大于x^n便可结束,道理如上一样,对最后结果无影响,            //为什么使用k+=i*i,其实质就是一个生成函数:1+x^(i*i)+x^2(i*i)+……,            //没有的项系数为0,对于有效的项刚累加a[j],            //不是加1的原因为可能a[]中不存在第j项,也就是说x^j的系数为0            for(k=0;k<=n;k++)//将结果保存在a[]中,将b[]清0,以便再循环使用            {   a[k]=b[k];b[k]=0;}    }        } int main(){    while(cin>>n && n)    {          fun(n);          cout<<a[n]<<endl;    } }