“猴子分队”的解题思路

在这个问题用到了动态规划,先在主程序的外面创建两个数组a和dp,分别储存n个猴子的力量值和猴子在某一个的最大力量值,和一个变量mmin,用于两队的猴子的力量值的差。

int a[22],mmin = 10000000,dp[100000];

在main函数中创建n(猴子数量)和sum(力量值总和)。

int n,sum = 0;
cin >> n;

用for循环输入a[i],sum加上a[i],表示这n只猴子的力量值总和。

for(int i = 1;i <= n;i++){
	cin >> a[i];
	sum += a[i];
} 

在输入之后,难点来了——将分队问题转换成背包问题(01问题)。把背包的容量看成sum/2,在平均分之后两边中最小的数就成了背包的容量;猴子的力量值就是背包问题中的重量(w)和价值(c)。

然后双重循环判断加入一只猴子的力量值和保留之前的力量值的大小,如果会超,那就保留。

for(int i = 1;i <= n;i++){
	for(int j = sum/2;j >= a[i];j--){ 
		dp[j] = max(dp[j],dp[j - a[i]] + a[i]); 
	}
} 

最后,在循环外面,找出两边力量值差值最小的数输出。

mmin = sum - dp[sum/2] * 2;
cout << mmin; 

 易错(难点):

在写这个程序时,比较简单的方法就是把这个问题改变一下思路,从分队的问题变成背包问题,这样对于只会做背包问题的人来说会更加简单。如果在题目中没有“容量”、“价值”和“重量”,那就在题目中找出这三个被隐藏的数。

心得:

这个问题拿到手里时是信心满满,觉得简单,不就是动态规划吗,一步一步地写,那成功不是信手拈来。但在做的时候才发现,没有容量、价值和重量。所以在老师讲完之后,才知道把不会的题通过转换可以改成我之前学过的知识,从而更简单地去做题目。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值