POJ 1664 放苹果

题目大意:中文

题目链接

注释代码:

/*    
 * Problem ID : POJ 1664 放苹果  
 * Author     : Lirx.t.Una    
 * Language   : C    
 * Run Time   : 0 ms    
 * Run Memory : 172 KB    
*/  

#include <stdio.h>

//maximum number of apples and plates,苹果和盘子的最大数量(10 + 1)
#define	MAXN		11

//memo,备忘录,记录每种情况下(i个苹果j个盘子)的分法数量
//经测试,最大的m[10][10]也只有42,所以使用char可以节省空间
char	mm[MAXN][MAXN] = { 0 };

char
par( int m, int n ) {//partition,划分,求m个苹果n个盘子的分法数量
	
	if ( mm[m][n] )//如果已经记录过则直接返回备忘录中的结果
		return mm[m][n];
	
	if ( 1 == m || 1 == n ) {//当苹果或盘子至少有一个为1时必定只有一种分法
		
		mm[m][n] = 1;
		return 1;//返回常数比返回数组元素节省了从数组中取数的时间
	}
	
	//分两种情况讨论
	//第一种是苹果数小于盘子数(m < n),就相当于par( m, m )
	//第二种是苹果数等于盘子数,即par( m, m ),因此第一种情况可以归结在该情况下
	//对于第二种情况,总共有两种情形:
	  //要么有空盘子要么没有空盘子
	  //无空盘子的情形就只有每个盘子里刚好都有一个苹果这么1种
	  //有空盘子的情形可以理解为至少有一个空盘子,那么所有苹果将会在剩下的m - 1个盘子中进行分配
	if ( m <= n )
		return mm[m][n] = 1 + par( m, m - 1 );
	
	//对于苹果多于盘子的情况也有两种情形
	//一种是无空盘,就等价于现在每个盘子中放上一个苹果(从而保证无空盘),
	  //然后在将剩余的m - n个苹果自由分配到这n个盘子中去
	//第二种情况是有空盘,同样,既然有空盘那么就至少会空出一个盘子,
	  //那么就相当于在剩下的n - 1个盘子中自由分配m个苹果了
	return mm[m][n] = par( m, n - 1 ) + par( m - n, n );
}

int
main() {
	
	int		nscn;
	int		m, n;
	
	scanf("%d", &nscn);
	while ( nscn-- ) {
		
		scanf("%d%d", &m, &n);
		printf("%d\n", par( m, n ));
	}
	
	return 0;
}
无注释代码:

#include <stdio.h>

#define	MAXN		11

char	mm[MAXN][MAXN] = { 0 };

char
par( int m, int n ) {
	
	if ( mm[m][n] )
		return mm[m][n];
	
	if ( 1 == m || 1 == n ) {
		
		mm[m][n] = 1;
		return 1;
	}
	
	if ( m <= n )
		return mm[m][n] = 1 + par( m, m - 1 );
	
	return mm[m][n] = par( m, n - 1 ) + par( m - n, n );
}

int
main() {
	
	int		nscn;
	int		m, n;
	
	scanf("%d", &nscn);
	while ( nscn-- ) {
		
		scanf("%d%d", &m, &n);
		printf("%d\n", par( m, n ));
	}
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值