ACM_支离破碎(递推dp)

支离破碎

Time Limit: 4000/2000ms (Java/Others)

Problem Description:

远古时期有一位魔王想向一座宫殿里的公主求婚。为了考验魔王的智力,太后给了他这样一道题:给出一串珠子(大小相同)共 n 个,现在要求魔王将所有的珠子分成不超过(<=)m 堆并求出所有可能的总情况数。考虑到m,n较大时,整座宫殿都可能放不下,现在只需要他求出总情况数 mod M 的答案,聪明的你能帮魔王解决这个问题吗?

Input:

第一行输入两个整数 n 和 m.第二行输入 M .其中:1<=m<=n<=10000;2<=M<=10000.

Output:

输出所有可能的情况数 mod M的值.

Sample Input:

4 3
100
4 2
100
100 20 
10000

Sample Output:

4
3
2873
解题思路:题目的意思就是有m个珠子放在n个堆(盘子)里,允许有的盘子空着不放,问有多少种不同的分法。此题解法跟这篇文章一样,博文链接:ACM_递推题目系列之三放苹果
AC代码(1533ms):
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=10005;
 4 int m,n,mod,dp[maxn][maxn];
 5 int main(){
 6     while(cin>>m>>n>>mod){
 7         for(int i=0;i<=m;++i){dp[i][0]=0;dp[i][1]=1;}
 8         for(int i=0;i<=n;++i)dp[0][i]=1;
 9         for(int i=1;i<=m;++i){
10             for(int j=1;j<=n;++j){
11                 if(i<j)dp[i][j]=dp[i][i];
12                 else dp[i][j]=dp[i][j-1]%mod+dp[i-j][j]%mod;
13                 //else dp[i][j]=(dp[i][j-1]%mod+dp[i-j][j]%mod)%mod;//这样会超时
14             }
15         }
16         cout<<dp[m][n]%mod<<endl;//注意最后一步要取模
17     }
18     return 0;
19 }

原文地址:https://www.cnblogs.com/acgoto/p/9129394.html