1 7 3样例输出
8
类似整数划分
递归:
digui函数里设置两个形参,digui(int n,int m)代表整数n划分成最大为m的划分个数。
比如n=6:
6; m=6
5+1; m=5
4+2,4+1+1; m=4
3+3,3+2+1,3+1+1+1; m=3
2+2+2,2+2+1+1,2+1+1+1+1; m=2
1+1+1+1+1+1 m=1
n=5:
5; m=5
4+1; m=4
3+2, 3+1+1; m=3
2+2+1, 2+1+1+1; m=2
1+1+1+1+1; m=1
n=3:
3; m=3
2+1; m=2
1+1+1; m=1
综上,
1)当n=m时,n的划分情况中,m肯定只有一种情况,所以 若n=m return 1+gidui(n,m-1);2)当 n==1||m==1 的时候,结果肯定是1;
3)当n>m时,digui(n,m)=digui(n-m,m)+digui(n,m-1);
比如(5,2)时,对应的应该是 2+2+1,2+1+1+1; 1+1+1+1+1。
而digui(5-2,2)对应的刚好是2+1 , 1+1+1,而digui(5,1)对应的刚好是 1+1+1+1+1
因此n>m时digui(n,m)=digui(n-m,m)+digui(n,m-1);
4)当n<m时,digui(n,m)=digui(n,n);
比如digui(6,4)=digui(2,4)+digui(6,3);这时的digui(2,4)应该对应4+2,4+1+1,即2,1+1;故为digui(2,2);
#include<iostream> using namespace std; int func(int n,int m){ if(n==1||m==1) return 1; if(n<m) return func(n,n); if(n==m) return 1+func(n,m-1); if(n>m) return func(n,m-1)+func(n-m,m); } int main() { int n,m,N; while(cin>>N) { for(int i=0;i<N;i++) { cin>>n>>m; printf("%d\n",func(n,m)); } } return 0; }