http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1255
整数划分问题 996ms险过..(递归法)
#include<cstdio> #include<string> #include<map> using namespace std; int n,mod; long long dps[500][500]; long long dp(int n,int m){ //n表示要拆分的整数,m表示拆成的数最大是几/拆成m个数的和 if(n<=1 || m==1)return 1; if(n<m)return dp(n,n); if(dps[n][m])return dps[n][m]; return dps[n][m]=(dp(n,m-1)+dp(n-m,m)); } int main(){ long long sum; for(int i=1;i<=400;i++) dps[i][i]=dp(i,i); while(scanf("%d %d",&n,&mod)!=EOF){ sum=0; for(int i=1;i<=n;i++) sum=(sum+dps[i][i])%mod; printf("%lld\n",sum); } }
(母函数法)也是896ms险过..(参见http://hi.baidu.com/syxcs123/item/c10acbf46818f34d922af258)
#include<stdio.h> #include<string> using namespace std; int n,mod; long long c1[500],c2[500]; int main(){ int i,j,k; memset(c2,0,sizeof(c2)); for(i=0;i<=400;i++) c1[i]=1; for(i=2;i<=400;i++){ //依次前i个括号乘积 for(j=0;j<=400;j++) for(k=0;k+j<=400;k+=i) c2[k+j]=(c2[k+j]+c1[j]); for(j=0;j<=400;j++){ c1[j]=c2[j]; c2[j]=0; } } while(scanf("%d %d",&n,&mod)!=EOF){ long long sum=0; for(i=1;i<=n;i++) sum=(sum+c1[i])%mod; printf("%lld\n",sum); } }
n^2的dp
#include <cstdio> #include <cstring> typedef long long ll; using namespace std; ll ans[410]; int main(){ int i,j; int n,mod; ans[0]=1; for(i=1;i<=400;i++) //枚举当前分解的最大的数 for(j=i;j<=400;j++){ ans[j]+=ans[j-i]; //把j分解成i和ans[j-i] } while(scanf("%d %d",&n,&mod)!=EOF){ long long sum=0; for(i=1;i<=n;i++) sum=(sum+ans[i])%mod; printf("%lld\n",sum); } }