2019.6.5
苹果放盘子问题,有盘子若干,苹果若干,盘子与苹果都完全相同,例如7个苹果,放入3个盘子,允许盘子为空,共有多少种方法?115和511是相同的方法,7个苹果3个盘子,答案是8种。
<一>暴力枚举
分析:手动枚举防止重复的方法就是通过有序排列,而选择从大到小的排序方法效率更高。
优点: 可以改造成可以打印出所有的排序情况的代码
注意点:++c表示的是指针所指向的数字加1,而c++表示的指针的位置向后移一位
#include<stdio.h>
void solve(int a,int b,int* c,int last)
{
if(b==1)
{
if(a<=last&&a>=0) ++*c;
return;
}
if(a==0){++*c;return;}
int minn=last;
if(a<minn)minn=a;
for(int i=minn;i>0;i--)solve(a-i,b-1,c,i);
}
int main(void)
{
int apple,dish,ans=0;
scanf("%d %d",&apple,&dish);
solve(apple,dish,&ans,apple+1);
printf("共有%d种排序方法",ans);
return 0;
}
改造成可打印排列的如下
#include<stdio.h>
int min(int a,int b){if(a<b)return a; return b;}
void print(int arr[],int cnt)
{
for(int i=0;i<cnt;i++)printf("%d ",arr[i]);
printf("\n");
}
int solve(int a,int b,int* c,int last,int arr[],int cnt)
{
if(b==1)
{
if(a<=last&&a>=0){++*c;arr[cnt]=a;print(arr,cnt+1);return 1;}
return 0;
}
if(a==0){++*c;print(arr,cnt);return 1;}
for(int i=min(a,last);i>0;i--)
{
arr[cnt]=i;
solve(a-i,b-1,c,i,arr,cnt+1);
}
}
int main(void)
{
int apple,dish,ans=0,arr[100];
scanf("%d %d",&apple,&dish);
solve(apple,dish,&ans,apple+1,arr,0);
printf("共有%d种排序方法",ans);
return 0;
}
<二>抓住本质写递归 --------from 硕硕
作者思路:首先是当盘子数目大于苹果数目时,多余的盘子是没有用的,所以这时候可以把多于的盘子拿走。当盘子数小于等于苹果数时,可以分为两种情况,有一个空盘子即有0存在的情况,跟所有盘子中都有苹果的情况。对于有0存在的情况,这个盘子存在和不存在并不影响分类数目,可以直接把这个盘子拿走。对于每个盘子中都有苹果的情况,从每个盘子中各拿走一个苹果后,也不影响分类数目。最后当没有苹果或者只有一个盘子的时候就是一种情况即(0个苹果b个盘子)(a个苹果1个盘子)。
我的理解:只有2个选择,要么处理苹果,要么处理盘子,处理苹果意味着把当前的盘子都放上一个苹果,处理盘子意味着减少一个盘子,去看少一个盘子的问题怎么处理,也就是另一个递归了。递归终止就是盘子数为1或者没有苹果了。
优点:运行速度快,效率高,比第一种方法快的多。
#include<stdio.h>
int solve(int a,int b)
{
if(a==0||b==1)return 1;
if(a<b)return solve(a,b-1);
else return solve(a,b-1)+solve(a-b,b);
}
int main(void)
{
int a,b;
scanf("%d %d",&a,&b);
int ans=solve(a,b);
printf("%d",ans);
}
<三>递推公式
思路:偶然看到某位dl博客用的是递推公式。
#include<stdio.h>
int main(void)
{
int a,b;
scanf("%d %d",&a,&b);
int all[100][100];
for(int i=0;i<=a;i++)
for(int j=0;j<=b;j++)
{
if(i==0||j==1){all[i][j]=1;continue;}
if(i>=j)all[i][j]=all[i-j][j]+all[i][j-1];
else all[i][j]=all[i][j-1];
}
printf("%d ",all[a][b]);
return 0;
}
测试代码放这里了
https://github.com/Mally-cj/mine/commit/9d463e9afd15e32a7b6c55fb6c46aed719a310ed