NOI 2.3.666放苹果 题解(C++)
这一次的题目可以说是非常的仁道了,连我这种浑身100%水分的人都可以不看题解解决 [滑稽],不知道对各位AK IOI的巨佬怎么样
【原题地址】请猛戳
懒得动手的就看下面的吧
666:放屁股 放苹果
总时间限制: 1000ms
内存限制: 65536kB
描述
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
输入
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
输出
对输入的每组数据M和N,用一行输出相应的K。
样例输入
1
7 3
样例输出
8
思路
首先我们可以看到这次的数据是非常的令人愉悦,显而易见 稍稍想一会儿就知道可以使用递归来解决,还有一个就是在递归中可以在不同的盘中放相同个数的苹果,k就是指已经不能放小于k个的苹果,避免重复。因为在这一题中重复只算一种,也不能剩下苹果,每一个苹果也都一样。怎么可能?
如果递归有点蒙的话可以到作者主页里翻一下。
不叨逼叨了,直接看代码吧
#include<bits/stdc++.h>
using namespace std;
int ans,t[25];
void f(int m/*当前还剩下多少苹果*/,int n/*第几个盘子*/,int num/*第几组数据*/,int k/*思路中有讲*/){
if(m == 0&&n == t[num]){//如果不剩下苹果或者N已经遍历完了
ans++;//方法数+1
return ;
}
if(n == t[num]&&m!=0){//到最后一个却还有剩苹果
return ;//方法数显然不能+1
}
for(int i = k;i<=m;i++){//考虑放i个苹果
f(m-i,n+1,num,i);
}
}
int main(){
int n,m[25];
cin>>n;
for(int i = 0;i<n;i++){
cin>>m[i]>>t[i];
}
for(int i = 0;i<n;i++){
ans = 0;//千万不能忘了清0,不然的话你可以试试,呵呵~
f(m[i],0,i,0);
cout<<ans<<endl;
}
}
好了,这题已经讲完了。