hdu-1028
一、递归
构造一个函数fun(int n,int m);
n表示输入的N,m表示组成N中的任意一个小项不超过m;
4 = 4;
4 = 3 + 1;
4 = 2 + 2;
4 = 2 + 1 + 1;
4 = 1 + 1 + 1 + 1;
分情况
1 m>n 例:fun(4,6)=fun(4,4);
fun(n,m)=fun(n,n);
2 m=n 例: fun(4,4)=1+fun(4,3); 要么小项中有4(此时只有一种情况),要么没有;
fun(n,m)=1+fun(n,m-1);
3 m<n 例: fun(4,2)=fun(2,2)+fun(4,1); 要么小项中有2(此时剩下4-2=2),要么没有2;
fun(n,m)=fun(n-m,m)+fun(n,m-1);
4 递归结束标志
n=1或m=1 此时为1;
#include <stdio.h>
int fun1(int n,int m){
if(n==1||m==1) return 1;
else if(m>n) return fun1(n,n);
else if(m==n) return fun1(n,m-1)+1;
else return fun1(n-m,m)+fun1(n,m-1);
}
int main(int argc, char *argv[]) {
int n;
while(~scanf("%d",&n)){
printf("%d\n",fun1(n,n));
}
return 0;
}
发现超时;
改进
#include <stdio.h>
#include<string.h>
int a[130][130];//dp方法
int fun1(int n,int m){
if(a[n][m]!=-1) return a[n][m];
else if(n==1||m==1) return a[n][m]=1;
else if(m>n) return a[n][m]=fun1(n,n);
else if(m==n) return a[n][m]=fun1(n,m-1)+1;
else return a[n][m]=fun1(n-m,m)+fun1(n,m-1);
}
int main(int argc, char *argv[]) {
int n;
memset(a,-1,sizeof(a));
while(~scanf("%d",&n)){
printf("%d\n",fun1(n,n));
}
return 0;
}
二、母函数
(1+x+x2+x3..)*(1+x2+x4+...)*......
#include <stdio.h> #include <stdlib.h> int a[130]; int b[130]; //暂放; int main(int argc, char *argv[]) { int n; while(~scanf("%d",&n)){ int i,j,k; for(i=0;i<=n;i++){ a[i]=1;//1*1+1*x+1*x2+..; b[i]=0; } for(i=2;i<=n;i++) //从(1+x2+x4...)开始 与上一个因式相乘 { for(j=0;j<=n;j++)//j表示指数 1+x+x2+x3+... { for(k=0;k+j<=n;k+=i) //表示指数 当i=2时表示1+x2+x4+x6..的指数 { b[j+k]+=a[j]; } } for(j=0;j<=n;j++){ //注意 不能是i a[j]=b[j]; b[j]=0; } } printf("%d\n",a[n]); } return 0; }
浙公网安备 33010602011771号