洛谷 P3052 USACO 摩天大楼里的奶牛Cows in a Skyscraper

本文介绍了一个经典的组合优化问题——电梯载牛问题。该问题要求在不超过电梯最大载重量的前提下,将若干只不同重量的牛从高层建筑运送至地面,目标是最小化电梯运行次数。文章提供了详细的输入输出格式及示例,并附带了使用深度优先搜索(DFS)来求解该问题的C++代码。

题目描述

A little known fact about Bessie and friends is that they lovestair climbing races. A better known fact is that cows really don't like goingdown stairs. So after the cows finish racing to the top of their favoriteskyscraper, they had a problem. Refusing to climb back down using the stairs,the cows are forced to use the elevator in order to get back to the groundfloor.

The elevator has a maximum weight capacity of W (1 <= W <=100,000,000) pounds and cow i weighs C_i (1 <= C_i <= W) pounds. Pleasehelp Bessie figure out how to get all the N (1 <= N <= 18) of the cows tothe ground floor using the least number of elevator rides. The sum of theweights of the cows on each elevator ride must be no larger than W.

给出n个物品,体积为w[i],现把其分成若干组,要求每组总体积<=W,问最小分组。(n<=18)

输入输出格式

输入格式:
* Line 1: N and W separated by a space.

* Lines 2..1+N: Line i+1 contains the integer C_i, giving theweight of one of the cows.

输出格式:
* A single integer, R, indicating the minimum number of elevator rides needed.

one of the R trips down the elevator.

输入输出样例

输入样例#1 

4 10 
5 
6 
3 
7 

输出样例#1 

3 

说明

There are four cows weighing 5, 6, 3, and 7 pounds. The elevatorhas a maximum weight capacity of 10 pounds.

We can put the cow weighing 3 on the same elevator as any othercow but the other three cows are too heavy to be combined. For the solutionabove, elevator ride 1 involves cow #1 and #3, elevator ride 2 involves cow #2,and elevator ride 3 involves cow #4. Several other solutions are possible forthis input.

题解:这道题目直接暴力枚举答案,然后进行DFS将这些牛进行分配,判断是否可以即可。

#include <cstdio>
#include <cstring>
int n,w,a[30],sum[30];
using namespace std;
bool dfs(int cow,int s)
{
	for (int i=1;i<=cow && i<=s;i++)
	  if (sum[i]+a[cow]<=w)
	  {
	  	sum[i]+=a[cow];
	  	if (cow==n) return 1;
	  	if (dfs(cow+1,s)) return 1;
	  	sum[i]-=a[cow];
	  }
	return 0;
}
int main()
{
	scanf("%d%d",&n,&w);
	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
	for (int i=1;i<=n;i++)
	{
		memset(sum,sizeof(sum),0);
		if (dfs(1,i))
		{
			printf("%d\n",i);
			return 0;
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值