【蓝桥第六周】奥运火炬登珠峰

RQNQJ PID202 / 奥运火炬登珠峰

题目描述 Description
    5月8日,在世界人民的共同关注下,象征着和平、友谊、圣洁的奥运火炬终于来到了世界之巅——珠穆朗玛峰……登上珠峰可不是所有人都能办得了的,火炬手们为了登山要使用特殊的装备。他有一个带2种气体的气缸:一个为氧气,一个为氮气。让火炬手需要各种的数量的氧和氮。火炬手有一定数量的气缸。每个气缸都有重量和气体容量。火炬手为了完成传递需要特定数量的氧和氮。他完成传递所需气缸的总重的最低限度的是多少?
例如:火炬手有5个气缸。每行三个数字为:氧,氮的(升)量和气缸的重量:

3 36 120
10 25 129
5 50 250
1 45 130
4 20 119

    如果火炬手需要5升的氧和60升的氮则总重最小为249 (1,2或者4,5号气缸)。你的任务就是计算火炬手为了完成传递需要的气缸的重量的最低值。
输入描述 Input Description
第一行有2整数t,a(1<=t<=21,1<=a<=79)。它们表示氧,氮各自需要的量。
第二行为整数n (1<=n<=1000)表示气缸的个数。
此后的n行,每行包括ti,ai,wi(1<=ti<=21,1<=ai<=79,1<=wi<=800)3整数。这些各自是:第i个气缸里的氧和氮的容量及汽缸重量。
输出描述 Output Description
仅一行包含一个整数,为火炬手完成传递所需的气缸的重量总和的最低值。
样例输入 Sample Input
5 60
5
3 36 120
10 25 129
5 50 250
1 45 130
4 20 119
样例输出 Sample Output
249

[解题思路]

        这类型的题是由01背包问题的一维数组解法扩展而来的,既然是扩展,那就是在原来的基础上改变即可,要注意的是这里需要满足的条件有两个(至少需要多少氧气和氮气),而之前的01背包需要满足的条件只有一个(不超过背包容量的情况下)。故可用二维数组来存储,另一点需要注意的是在01背包中,是不超过背包容量,故v>=weight才继续,而这里是至少要有多少氧气和氮气,故k(氮气)>=0,j(氧气)>=0,而当氧气和氮气满足,即超过所需的,都存在dp[Oxygen][Nitrogen]。

[代码实现]

#include<iostream>
using namespace std;
int min(int a,int b)
{
	return 	a<b?a:b;
}
struct Node /*	结构体存放氧气、氮气、重量*/
{
	int oi,ni,wi;
} node[1001];
int main ()
{
	int Oxygen,Nitrogen;
	cin>>Oxygen>>Nitrogen;
	int dp[22][80];
	int num;
	cin>>num;
	for (int i=0;i<num;i++)
	{
		cin>>node[i].oi>>node[i].ni>>node[i].wi;
	}

	for (int i=0;i<22;i++)
	{
		for (int j=0;j<80;j++)
		{
			dp[i][j]=INT_MAX;
		}
	}
	dp[0][0]=0;
	for(int i=0;i<num;i++)
		for (int j=Oxygen;j>=0;j--)
			for (int k=Nitrogen;k>=0;k--)  /* 与01背包的最大容量不同v>=weight[i],因为这里要求的是要等于或者超过,而不是不超过 */
			{
				if (dp[j][k]!=INT_MAX) /*因为INT_MAX再加上一个数会超出范围,所以不能等于INT_MAX*/
				{
					int x=min(j+node[i].oi, Oxygen);
					int y=min(k+node[i].ni, Nitrogen);
					if (dp[x][y]>dp[j][k]+node[i].wi) 
					{
						dp[x][y]=dp[j][k]+node[i].wi;/* 若当前是(氧气、氮气)小于所需的,计算值小的,若大于所需的(氧气、氮气),存在dp[x][y] */
					}
				}
			}
	cout<<dp[Oxygen][Nitrogen];
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值