题目:

有一个体积为N的箱子和两种数量无限的宝物。宝物1的体积为S1,价值为V1;宝物2的体积为S2,价值为V2.输入均为32位带符号整数。计算最多能装多大价值的宝物,每种宝物都必须拿非负整数个。

思路:

看完紫书的分析,不知道怎么判断N/S1、N/S2到底在那个范围内较大、较小,于是就用了下面的方法,不过这个方法效率低的很

S1个宝物2的体积=S2个宝物1的体积,他们的价值就是S1*V2和S2*V1.

1.如果S1*V2 > S2*V1,那么宝物1最多拿S2-1个,因为一旦满了S2个宝物1,这些就可以转换成S1个宝物2。然后枚举宝物1就可以了,注意这里范围是min{S2-1,N/S1}。

2.如果S1*V2 < S2*V1,那么宝物2最多拿S1-1个,因为一旦满了S1个宝物2,这些就可以转换成S2个宝物1。然后枚举宝物2就可以了,注意这里范围是min{S1-1,N/S2}。

3.如果S1*V2 = S2*V1,那么如果V1 > V2,就尽量多拿宝物1,相反就尽量多拿宝物2。

然后写代码就ok了。

代码:

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define MAX 1000000009
#define FRE() freopen("in.txt","r",stdin)
#define FRO() freopen("out.txt","w",stdout)
using namespace std;
typedef long long ll;
const int maxn = ;
ll n,s1,v1,s2,v2; int main(){
//FRE();
ios::sync_with_stdio(false);
int T,kase=;
cin>>T;
while(T--){
cin>>n>>s1>>v1>>s2>>v2;
ll a = s1*v2, b= s2*v1;
ll ans = ;
if(a>b){//对应上述情况1
for(ll i=; i<min(s2,n/s1+); i++){
ll num = (n-i*s1)/s2;
ans = max(ans,i*v1+num*v2);
}
}else if(a<b){//对应上述情况2
for(ll i=; i<min(s1,n/s2+); i++){
ll num = (n-i*s2)/s1;
ans = max(ans,i*v2+num*v1);
}
}else{//情况3中按各个宝物价格大小决定枚举那个宝物
if(v1>v2){
ll i=;
for(; i<(n/s1); i++){
ll num = (n-i*s1)/s2;
ans = max(ans, i*v1+num*v2);
}
}else {
ll i=;
for(; i<(n/s2); i++){
ll num = (n-i*s2)/s1;
ans = max(ans, i*v2+num*v1);
}
}
}
cout<<"Case #"<<++kase<<": "<<ans<<endl;
}
return ;
}

AC之后在VJ中发现了一个判断较大较小的方法做的,于是我又改了改自己写的代码,发现当这个界限设在1e3~1e4的时候,搜索的效率会达到最大。

当(N/S1)较小的时候,就枚举宝物1,尽量多拿宝物2,当(N/S2)较小的时候,就枚举宝物2,尽量多拿宝物1,如果两者都较小的时候,就按上边的1、2两个情况进行分析。

代码:

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define MAX 1e3
#define FRE() freopen("in.txt","r",stdin)
#define FRO() freopen("out.txt","w",stdout)
using namespace std;
typedef long long ll;
const int maxn = ;
ll n, s1, v1, s2, v2; int main() {
//FRE();
ios::sync_with_stdio(false);
int T, kase = ;
cin >> T;
while(T--) {
cin >> n >> s1 >> v1 >> s2 >> v2;
ll c = n / s1, d = n / s2;
ll a = s1 * v2, b = s2 * v1;
ll ans = ;
if(c < MAX) {
for(ll i = ; i < (n / s1 + ); i++) {
ll num = (n - i * s1) / s2;
ans = max(ans, i * v1 + num * v2);
}
} else if(d < MAX) {
for(ll i = ; i < (n / s2 + ); i++) {
ll num = (n - i * s2) / s1;
ans = max(ans, i * v2 + num * v1);
}
} else if(a > b) {
for(ll i = ; i < min(s2, n / s1 + ); i++) {
ll num = (n - i * s1) / s2;
ans = max(ans, i * v1 + num * v2);
}
} else if(a <= b) {
for(ll i = ; i < min(s1, n / s2 + ); i++) {
ll num = (n - i * s2) / s1;
ans = max(ans, i * v2 + num * v1);
}
}
cout << "Case #" << ++kase << ": " << ans << endl;
}
return ;
}

最新文章

  1. JSP动作元素——————理论篇
  2. Markdown 语法总结
  3. 【Win10开发】处理PC上的后退键
  4. spring入门教程——笔记
  5. 学习笔记:腾讯云——服务器mysql操作
  6. [转]ORACLE DBA TRANSACTIONS
  7. mysql模拟rownum的一个方法
  8. CodeForces Round #287 Div.2
  9. 不可不知的 Android strings.xml 那些事
  10. java web开发 高并发处理
  11. 使用 vi 命令
  12. centos后台运行Python
  13. 关于JS的一些案例,setInterval,动态图片
  14. Laravel 项目中编写第一个 Vue 组件
  15. web移动端浮层滚动阻止window窗体滚动JS/CSS处理
  16. mybatis教程1(基本使用)
  17. Ubuntu命令行
  18. docker 网络实践
  19. BZOJ.2738.矩阵乘法(整体二分 二维树状数组)
  20. HTML5+Bootstrap 学习笔记 4

热门文章

  1. 打印二叉树中距离根节点为k的所有节点
  2. RDA CoreDump 实例
  3. Python 私有化类的属性
  4. /bin/bash: jar: command not found(转载)
  5. va_start和va_end使用详解(转载)
  6. Akka源码分析-Cluster-Distributed Publish Subscribe in Cluster
  7. (快排)51NOD 1018 排序
  8. javascript实现引用数据类型的深拷贝和浅拷贝详解
  9. STL内存分配方式
  10. PostgreSQL与MySQL比较