1. 程式人生 > >hdu 1028 && hdu 1398 ——生成函式

hdu 1028 && hdu 1398 ——生成函式

題目:http://acm.hdu.edu.cn/showproblem.php?pid=1028

就是可以用任意個1、2、3、...,所以式子寫出來就是這樣:(1+x+x^2+...)(1+x^2+x^4+...)(1+x^3+x^6+...)...(1+x^n+x^(2*n)+...)... 因為求 x^n 係數,所以再往後的式子就沒有貢獻了,求到第 n 個式子即可。

一個x^2就像一條邊一樣,可以讓第 k 項的係數轉移給第 k+2 項。按這個思路寫程式碼就行了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include
<algorithm> using namespace std; const int N=125; int n,a[N],b[N]; int main() { while(scanf("%d",&n)==1) { for(int i=0;i<=n;i++) a[i]=1,b[i]=0; for(int i=2;i<=n;i++) { for(int j=0;j<=n;j++) for(int k=0;j+k<=n;k+=i) b[j+k]+=a[j];
for(int j=0;j<=n;j++) a[j]=b[j],b[j]=0; } printf("%d\n",a[n]); } return 0; }

題目:http://acm.hdu.edu.cn/showproblem.php?pid=1398

同上。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=305,M=17;
int n,a[N],b[N],w[M+5]; int main() { for(int i=1;i<=M;i++)w[i]=i*i; while(1) { scanf("%d",&n);if(!n)return 0; for(int i=0;i<=n;i++) a[i]=1,b[i]=0; for(int i=2;i<=M;i++) { for(int j=0;j<=n;j++) for(int k=0;j+k<=n;k+=w[i]) b[j+k]+=a[j]; for(int j=0;j<=n;j++) a[j]=b[j],b[j]=0; } printf("%d\n",a[n]); } }