动态规划-捞鱼问题

题目

3个桶,5条鱼,每个桶中可放置0~3条鱼,请问共有排列有多少种 ?

分析过程

在这里插入图片描述

递归及动态规划代码

#include <stdio.h>
#include <stdlib.h>

/************************************************
 * 递归方式求剩余bucket个桶放置剩余fish条鱼的总分配方法
 * **********************************************
 * @param int bucket		表示当前剩余多少个桶
 * @param int fish			表示当前剩余多少条鱼
 * @param int bugket_max	表示每个桶最多分配条数
 * @return long result
 * **********************************************
 */
long dfs(int bucket, int fish, int bucket_max) {
	if ( bucket == 1 ) {
		if ( fish >= 0 && fish <= bucket_max ) {
			return 1;
		} else {
			return 0;
		}
	}
	 
	long result = 0;
	for (int i = 0; i <= bucket_max && fish-i >= 0; i++) {
		result += dfs(bucket-1, fish-i, bucket_max);
	}

	return result;
}

/************************************************
 * 动态规划求剩余bucket个桶放置剩余fish条鱼的总分配方法
 * **********************************************
 * @param int bucket		表示当前剩余多少个桶
 * @param int fish			表示当前剩余多少条鱼
 * @param int bugket_max	表示每个桶最多分配条数
 * @return long result
 * **********************************************
 */
long dp(int bucket, int fish, int bucket_max) {
	long **tmp = (long **)calloc(bucket+1, sizeof(long *));
	for ( int i = 0; i < fish+1; i++ ) {
		tmp[i] = (long *)calloc(fish+1, sizeof(long)); //前i个桶放j条鱼的个数
	}

	for ( int i = 0; i < bucket_max+1 && i < fish+1; i++ ) {
		tmp[1][i] = 1; //初始化第一个桶放小于bucket_max的值都为1
	}

	for ( int i = 2; i < bucket+1; i++ ) {
		for ( int j = 0; j < fish+1; j++) {
			for ( int k = 0; k < bucket_max+1 && j - k >= 0; k++ ) {
				tmp[i][j] += tmp[i-1][j-k];
			}
		}
	}

	return tmp[bucket][fish];
}

int main() {
    long res = dfs(3, 5, 3);
    long res_dp = dp(3, 5, 3);
	long res_1 = dfs(10, 20, 10);
    long res_dp_1 = dp(10, 20, 10);
	long res_2 = dp(20, 20, 10);
    long res_dp_2 = dp(20, 30, 10);
    printf("res = %ld res_dp = %ld\n", res, res_dp);
    printf("res_1 = %ld res_dp_1 = %ld\n", res_1, res_dp_1);
	printf("res_2 = %ld res_dp_2 = %ld\n", res_2, res_dp_2);
    
    return 0;
}

/*********************执行结果*********************
******** 运行环境: macos sizeof(long) = 8 *********
res = 12 res_dp = 12
res_1 = 9528805 res_dp_1 = 9528805
res_2 = 68785126410 res_dp_2 = 18145201435834
*************************************************/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值