XMU 1255

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);
    }
}


 

你可能感兴趣的:(XMU 1255)