放苹果 POJ - 1664
https://vjudge.net/problem/POJ-1664
题意:
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?
DFS
思路
用的深搜的办法,每次后面的数都会 大于等于 前面的数字。
代码:
int n, m, sum; void dfs(int x, int step, int y) { if (step > m || x > n) return; else if (x == n && step == m) { sum++; return; } for (int i = y; i <= n; i++) dfs(i + x, step + 1, i); } void solve() { int t; cin >> t; while (t--) { sum = 0; cin >> n >> m; dfs(0, 0, 0); cout << sum << endl; } }
DP
原文
思路
设f[m][n]表示把m个苹果放到n个盘子里的不同方法的种数。
-
当盘子数n为1的时候,只有一种放法,就是把所有苹果放到一个盘子里。
-
当苹果数m为1的时候,也只有一种放法,因为盘子之间并无顺序,所以不管这个苹果放在哪个盘子里,结果都算一个。
-
当m<n时,m个苹果最多只能放到m个盘子中去(一个盘子里放一个),盘子有多余的。此时,实际上就相当于把m个苹果放到m个盘子里一样,也就是f[m][m]。
-
当m>=n时,可分两种情况讨论。
-
- 一种是至少有一个盘子里不放苹果,这就相当于f[m][n-1];
-
- 另一种是先取出n个苹果一个盘子里放一个,再将剩下的m-n个苹果放到n个盘子里去,即f[m-n][n]。
代码:
int n, m; int dp[N][N]; void solve() { int t; cin >> t; while (t--) { cin >> n >> m; dp[0][0] = 1; for (int i = 1; i <= m; i++) { for (int j = 0; j <= n; j++) { if (j - i >= 0) dp[i][j] = dp[i - 1][j] + dp[i][j - i]; else dp[i][j] = dp[i - 1][j]; } } printf("%d\n", dp[m][n]); } }
母函数模板题(待学)
母函数文章
思路
代码:
//母函数模板题:M个相同球放到N个相同的盒子中 G(x) = (1+x+x^2+x^3+...x^k+...)*(1+x+x^2+x^3+...x^k+...)*...(一共有 n 项)我们要求的就是x^m前面的系数 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<set> #include<cmath> using namespace std; int n; struct Z{ int val; int num; }z[10000]; int ans[100005],ans0[100005]; int main(){ int t; cin>>t; while(t--){ int m,n; cin>>m>>n; for(int i=0;i<=m;i++){ ans[i]=1; ans0[i]=0; } for(int i=2;i<=n;i++){ for(int j=0;j<=m;j++){ for(int k=0;j+k<=m;k+=i) ans0[j+k]+=ans[j]; } for(int j=0;j<=m;j++){ ans[j]=ans0[j]; ans0[j]=0; } } cout<<ans[m]<<endl; } }
本文作者:kingwzun
本文链接:https://www.cnblogs.com/kingwz/p/16575037.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步