这道题目相当于是把n个苹果放m个盘子里的一道题.
C++ 代码
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
int f(int x,int y){
if(x == 0) return 1;//没有苹果,全部盘子为0
if(y == 0) return 0;//没有盘子,没法放
if(y > x){//盘子数大于苹果数,至多只能x个盘子上都放一个
return f(x,x);
}
return f(x - y, y) + f(x, y - 1);//盘子数小于等于苹果数 -> 分类讨论: 有盘子为空,没有盘子为空
//有盘子为空的时候即至少有一个盘子为空,f(x,y-1);没有盘子为空即最少每个盘子都有一个,f(x-y,y)
}
int main(){
int t,n,m;//n个苹果分到m个盘子里去,运行盘子为空
cin >> t;
while(t --){
cin >> n >> m;
cout << f(n,m) << endl;
}
return 0;
}
实际上我们可以发现,在递归的过程中就是要用到之前的数据,继而这道题可以转换为记忆化搜索将结果保存来做,即dp做法,但是这个dp是从递归去思考出来的- -而不是像灿总那样直接思考dp做法.
#include<iostream>
#include<cstdio>
using namespace std;
int a[25][25],m,n;
int main()
{
int t,m,n;
for(m=0;m<=10;m++)
{
for(n=0;n<=10;n++)
{
if(m<n)a[m][n]=a[m][m];
else if(m==0)a[m][n]=1;
else if(n==0)a[m][n]=0;
else a[m][n]=a[m-n][n]+a[m][n-1];
}
}
scanf("%d",&t);
for(int i=1;i<=p;i++)
{
scanf("%d%d",&m,&n);
printf("%d\n",a[m][n]);
}
return 0;
}
我这个算法貌似也蛮好的哦:
谢谢楼主的分享,看后思路清晰很多!
但刚刚在写题时,有一点疑惑:为什么要先考虑
if(果子==0)
的情况,再考虑if(盘子==0)
的情况(即为什么a[0][0]=1
)呢?思考后得出如下结论(原因):是为了保证
a[0][n] = a[0][0]
时,a[0][n]
的值不会错我的具体分析过程如下(从考虑可能会用到a[0][0]值的两种情况,切入分析):
情况①: 在”
a[m][n]=a[m-n][n]+a[m][n-1]
“中用到了a[0][0]
- [前提] 符合
m≥n
且m,n≠0
- i.
a[m-n][n]=a[0][0]
, 即m=n=0
→ 不符合m,n≠0
的前提,舍去- ii.
a[m][n-1]=a[0][0]
, 即m=0且n=1
→ 不符合m≥n
的前提,舍去情况②: 在
a[m][n]=a[m][m]
中用到了a[0][0]
- 【前提】符合
m<n
- 此类仅有当
m=0;n=1,2,...,n
时符合, 即a[0][n](n>0) = a[0][0]
- 又由于
a[0][n](n>0)
, 属于有盘子, 却没苹果的情况, 此类情况拥有唯一方案:每个盘子均为空 ==> 故a[0][n](n>0) = 1;
- 而代码中
a[0][n] = a[0][0]
, 因此要把a[0][0]
设为1, 才能保证a[0][n]
的值不会错.综上,找到为什么设置
a[0][0]=1
的原因:为了保证a[0][n] = a[0][0]
时,a[0][n]
的值不会错看看我写的思路,感觉也是一种新的集合划分方法
大佬nb 这思路顶的很 但是倒数第八行的p应该是t把?
..不是大佬 。。。 是吧 写错了符号 /捂脸
为什么y总的DP代码 f[0][0] 为什么等于1啊 0个盘子 0个苹果 连盘子都没有 为什么会有1种方案呢
他这里也是1啊
大佬,n为什么要从0开始呢,0的盘子为什么有意义呢
请问楼主,为什么DP做法中
if(m<n)a[m][n]=a[m][m];
要写在
else if(m==0)a[m][n]=1;
else if(n==0)a[m][n]=0;
前面数据才正确
真大佬理解!
6666666666666666666
果子=0和盘子=0的情况可以交换的吧,你看原题3428. 放苹果
tql!!!!!!!!!!!!!!!!!!!!!感觉了数学和算法结合的魅力!
我直接给你跪了,md,太强了,一下就懂了,呜呜呜呜!!!
哥,我给你跪下了,看到你的讲解,我不禁潸然泪下,我为什么没有想到呢
Orz
为什么判断循环那里要先判断m《n啊 我先判断m==0就出错了
在 f 函数里 盘子数<=苹果数 时,不会有盘子为空的时候呀 , 而且为什么最后return两个数的和呀??
可以不放苹果到盘子里面啊,没有硬性规定一定要放吧
牛啊 啥时候我也能练出来这种解题思维就好了
这题姐,就很棒
很明了
讲的比Y总还清楚了
🐂
牛啊
这好理解些!