一中OJ #3514 礼物 | 暴搜 + 剪枝 | 解题报告

本文针对一中OJ编号3514的宝物装载问题进行详细解析,通过枚举策略将时间复杂度降至o(sqrt(n)),并提供四种不同情况的解决方案,确保高效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一中OJ | #3514 礼物

时限 1000MS/Case 内存 128MB/Case





题目描述

你有一个体积为N的箱子和两种数量无限的宝物。宝物1的体积为S1,价值为V1,宝物2的体积为S2,价值为V2。你的任务是计算箱子最多能装多大价值的宝物。注意每种宝物都必须拿非负整数个。

输入格式

多组数据,每组数据占一行,包含五个整数:N,S1,V1,S2,V2,他们的意义如题目描述。

输出格式

每组数据输出一行,表示箱子能装入的宝物的最大价值。

样例输入

100 1 1 2 2
100 34 34 5 3 

样例输出

100

86

数据范围

N,S1,V1,S2,V2均为32位带符号整数。
最多不超过100组数据。

----------------------------------------------------------

题目分析

枚举题,需要将时间复杂度降到o(sqrt(n))比较好过

所以将每组数据划分四种情况

1.当S1 == S2

这种很简单就不用说了

2.当S1 >= sqrt(n) 且 S1 >= S2

枚举S1的个数,算最大的ans

3.当S2 >= sqrt(n) 且 S2 >= S1

同(2.),枚举S2的个数,算最大的ans

4.当S1 < sqrt(n) 且 S2 < sqrt(n)

以S1*S2为一个单位,假设选择S2个物品1,S1个物品2,那么总体积都是S1*S2,选择物品1的价值就是S2*V1,物品2是S1*V2。这样就可以最优化选择一种物品。剩下的部分重复(2.)(3.)步骤即可

----------------------------------------------------------

代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#define hashsize 1000003
#define inf 0x7f7f7f7f
using namespace std;
int main()
{
//	freopen("Outp.txt","w+",stdout);
	long long n,s1,s2,v1,v2;
	while(cin>>n>>s1>>v1>>s2>>v2)
	{
		if(s1==s2)
		{
			cout<<(long long)(n/s1)*max(v1,v2)<<endl;
			continue;
		}
		long long c1=0,c2=0,ans=0,subb=0;
		if(s1>s2 && s1*s1>=n) //当s1比较大 
		{
			for(c1=0;c1*s1<=n;c1++)
			{
				ans=max(ans,(long long)c1*v1+(n-c1*s1)/s2*v2);
			}
		}
		else if(s2>s1 && s2*s2>=n) //当s2比较大 
		{
			for(c2=0;c2*s2<=n;c2++)
			{
				ans=max(ans,(long long)c2*v2+(n-c2*s2)/s1*v1);
			}
		}
		else
		{
			if(s1*v2>s2*v1) //取物品2更划算
			{
				ans=(n/(s1*s2))*s1*v2; //先取尽量多的物品2
				n=n%(s1*s2);
				if(s1>s2 && s1*s1>=n) //当s1比较大 
				{
					for(c1=0;c1*s1<=n;c1++)
					{
						subb=max(subb,c1*v1+(n-c1*s1)/s2*v2);
					}
				}
				else if(s2>s1 && s2*s2>=n) //当s2比较大 
				{
					for(c2=0;c2*s2<=n;c2++)
					{
						subb=max(subb,c2*v2+(n-c2*s2)/s1*v1);
					}
				}
				ans+=subb;
			}
			else //取物品1更划算 
			{
				ans=(n/(s1*s2))*s2*v1;
				n=n%(s1*s2);
				if(s1>s2 && s1*s1>=n) //当s1比较大 
				{
					for(c1=0;c1*s1<=n;c1++)
					{
						subb=max(subb,c1*v1+(n-c1*s1)/s2*v2);
					}
				}
				else if(s2>s1 && s2*s2>=n) //当s2比较大 
				{
					for(c2=0;c2*s2<=n;c2++)
					{
						subb=max(subb,c2*v2+(n-c2*s2)/s1*v1);
					}
				}
				ans+=subb;
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}



### XTUOJ平台上的A+B问题 #### 题目描述 XTUOJ平台上的A+B问题是经典的编程入门题目之一。该题要求对于给定的一对整数\(A\)和\(B\),计算并输出它们的和[^1]。 #### 输入输出说明 程序应能够接收多组测试数据,每组数据占一行,包含两个整数\(A\)和\(B\)(\(-10^{9} \leq A,B \leq 10^{9}\)),中间由单个空格分隔。对于每一组输入的数据,在单独的一行中输出对应的\(A + B\)的结果[^2]。 #### Python实现方案 下面是一个简单的Python版本解决方案: ```python while True: try: a, b = map(int, input().split()) print(a + b) except EOFError: break ``` 此代码片段通过循环读取标准输入直到遇到文件结束符EOF,并针对每次有效的输入执行加法运算后打印结果。 #### C++实现方式 以下是采用C++编写的解决方法: ```cpp #include <iostream> using namespace std; int main() { int a, b; while (cin >> a >> b) { cout << a + b << endl; } return 0; } ``` 这段代码同样实现了持续接受用户输入直至无新输入为止的功能,期间完成相应的两数相加操作并显示答案[^4]。 #### C语言实现途径 这里给出基于C语言的一个实例: ```c #include <stdio.h> int main() { int a, b; while (~scanf("%d %d", &a, &b)) { // 使用~来判断是否到达文件结尾 printf("%d\n", a + b); } return 0; } ``` 上述代码利用`scanf()`函数特性处理多个案例下的加法任务,当无法再成功扫描到新的数值时自动终止程序运行[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值