题目:http://acm.hdu.edu.cn/showproblem.php?pid=1028
整数划分,每个数可以用无限次;
所以构造 f(x) = (1+x+x2+x3+...)(1+x2+x4+...)(1+x3+x6+...)...(1+xn)
乘起来后的 xn 的系数就是方案数;
用两个数组做即可,从第一个括号开始一个一个乘,f[i] 表示此时 xi 项的系数,后面每乘过来一个括号,相当于多了一种转移,所以加上。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int const xn=125; int n,f[xn],t[xn]; int main() { while(scanf("%d",&n)==1) { for(int i=0;i<=n;i++)f[i]=1,t[i]=0; for(int i=2;i<=n;i++) { for(int j=0;j<=n;j++) for(int k=0;k<=n;k+=i)t[j+k]+=f[j]; for(int j=0;j<=n;j++)f[j]=t[j],t[j]=0; } printf("%d\n",f[n]); } return 0; }
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1398
同上。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int const xn=305; int n,f[xn],t[xn]; int main() { n=300; for(int i=0;i<=n;i++)f[i]=1,t[i]=0; for(int i=2;i<=17;i++) { int s=i*i; for(int j=0;j<=n;j++) for(int k=0;j+k<=n;k+=s)t[j+k]+=f[j]; for(int j=0;j<=n;j++)f[j]=t[j],t[j]=0; } while(1) { scanf("%d",&n); if(!n)return 0; printf("%d\n",f[n]); } }
原文地址:https://www.cnblogs.com/Zinn/p/10025519.html
时间: 2024-11-10 01:01:07