1514: Packs

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 61  Solved: 4
[Submit][Status][Web Board]

Description

Give
you n packs, each of it has a value v and a weight w. Now you should
find some packs, and the total of these value is max, total of these
weight is equal to m.

Input

First line is a number T( T ≤ 5) represent the test cases.
Then for each set of cases, first line is n (1 ≤ n ≤ 40) and m (1 ≤ m
< 2^31), follow n line each is Wi (1 ≤ Wi < 2^31) and Vi (-2^31
< Vi < 2^31).

Output

Each case a line for max value.(Each set of inputs to ensure the solvability)

Sample Input

2
3 3
1 1
2 2
3 4
5 2
1 -5
1 -8
1 0
1 -2
1 5

Sample Output

4
5 注意:这里要求是满足总重量必须固定,而不是接近总重量。这就成了直接折半枚举,map大法就行了。
 #include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long LL;
const long long INF=99999999999999999LL;
const int EXP=1e-;
const int MS=; map<LL,LL> mp;
int n;
LL W; LL w[MS],v[MS]; void solve()
{
mp.clear();
int n1=n/;
for(int i=;i<(<<n1);i++)
{
LL sw=,sv=;
for(int j=;j<n1;j++)
{
if((i>>j)&)
{
sw+=w[j];
sv+=v[j];
}
}
mp[sw]=max(mp[sw],sv);
}
LL ans=-INF;
for(int i=;i< <<(n-n1);i++)
{
LL sw=,sv=;
for(int j=;j<(n-n1);j++)
{
if((i>>j)&)
{
sw+=w[n1+j];
sv+=v[n1+j];
}
}
if(mp.count(W-sw))
ans=max(ans,mp[W-sw]+sv);
}
printf("%lld\n",ans);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%lld",&n,&W);
for(int i=;i<n;i++)
scanf("%lld%lld",&w[i],&v[i]);
solve();
}
return ;
}
如果是重量不大于 W ,那么就要折半枚举+二分查找。
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long LL;
const int INF=0x4fffffff;
const int EXP=1e-;
const int MS=; int n;
LL W;
LL w[MS],v[MS];
struct node
{
LL w,v;
bool operator <(const node &a) const //注意一定要加上const
{
return w<a.w||(w==a.w&&v<a.v);
}
}nodes[<<(MS/)]; LL find(LL w,int cnt)
{
int l=,r=cnt;
while(r-l>) // 左闭右开区间处理起来更方便。
{
int mid=(l+r)/;
if(nodes[mid].w<=w)
l=mid;
else
r=mid;
}
return nodes[l].v;
} void solve()
{
int n1=n/;
int cnt=;
for(int i=;i<(<<n1);i++)
{
LL sw=,sv=;
for(int j=;j<n1;j++)
{
if((i>>j)&)
{
sw+=w[j];
sv+=v[j];
}
}
nodes[cnt].w=sw;
nodes[cnt++].v=sv;
}
sort(nodes,nodes+cnt);
int last=;
for(int i=;i<cnt;i++)
{
if(nodes[last].v<nodes[i].v)
{
nodes[++last]=nodes[i];
}
}
cnt=last+;
LL ans=;
for(int i=;i< <<(n-n1);i++)
{
LL sw=,sv=;
for(int j=;j<(n-n1);j++)
{
if((i>>j)&)
{
sw+=w[n1+j];
sv+=v[n1+j];
}
}
if(sw<=W)
{
LL tv=find(W-sw,cnt);
ans=max(ans,sv+tv);
}
}
printf("%lld\n",ans);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%lld",&n,&W);
for(int i=;i<n;i++)
scanf("%lld%lld",&w[i],&v[i]);
solve();
}
return ;
}
 
 

CSU OJ PID=1514: Packs 超大背包问题,折半枚举+二分查找。的更多相关文章

  1. (容量超大)or(容量及价值)超大背包问题 ( 折半枚举 || 改变 dp 意义 )

    题意 : 以下两个问题的物品都只能取有且只有一次 ① 给你 N 个物品,所有物品的价值总和不会超过 5000, 单个物品的价格就可达 10^10 ,背包容量为 B ② 给你 N (N ≤ 40 ) 个 ...

  2. poj3977(折半枚举+二分查找)

    题目链接:https://vjudge.net/problem/POJ-3977 题意:给一个大小<=35的集合,找一个非空子集合,使得子集合元素和的绝对值最小,如果有多个这样的集合,找元素个数 ...

  3. Subset---poj3977(折半枚举+二分查找)

    题目链接:http://poj.org/problem?id=3977 给你n个数,找到一个子集,使得这个子集的和的绝对值是最小的,如果有多种情况,输出子集个数最少的: n<=35,|a[i]| ...

  4. Subset POJ - 3977(折半枚举+二分查找)

    题目描述 Given a list of N integers with absolute values no larger than 10 15, find a non empty subset o ...

  5. 中南林业大学校赛 I 背包问题 ( 折半枚举 || 01背包递归写法 )

    题目链接 题意 : 中文题 分析 :  价值和重量都太过于大,所以采用折半枚举的方法,详细可以看挑战的超大背包问题 由于 n <= 30 那么可以不必直接记录状态来优化,面对每个用例 直接采用递 ...

  6. POJ 3977 Subset(折半枚举+二分)

    SubsetTime Limit: 30000MS        Memory Limit: 65536KTotal Submissions: 6754        Accepted: 1277 D ...

  7. POJ 2549 Sumsets(折半枚举+二分)

    Sumsets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11946   Accepted: 3299 Descript ...

  8. Codeforces H. Prime Gift(折半枚举二分)

    题目描述: Prime Gift time limit per test 3.5 seconds memory limit per test 256 megabytes input standard ...

  9. POJ 2785 4 Values whose Sum is 0(折半枚举+二分)

    4 Values whose Sum is 0 Time Limit: 15000MS   Memory Limit: 228000K Total Submissions: 25675   Accep ...

随机推荐

  1. 第三百二十八天 how can I 坚持

    今天电脑快把我搞疯了,一天得死机快十次,不知道怎么回事,最后升级了win10,感觉就是比较好. 哎,成了这个样子,当初为什么又让我抽中了那个签,搞不懂啊,这都是为啥. 我哪里错了,还是冥冥中自有天意, ...

  2. CentOS下MySQL 5.7.9编译安装

    MySQL 5.7 GA版本的发布,也就是说从现在开始5.7已经可以在生产环境中使用,有任何问题官方都将立刻修复. MySQL 5.7主要特性: 更好的性能:对于多核CPU.固态硬盘.锁有着更好的优化 ...

  3. 【转】Java中只有按值传递,没有按引用传递!

    原文链接:http://guhanjie.iteye.com/blog/1683637 今天,我在一本面试书上看到了关于java的一个参数传递的问题: 写道 java中对象作为参数传递给一个方法,到底 ...

  4. URAL 2070 Interesting Numbers (找规律)

    题意:在[L, R]之间求:x是个素数,因子个数是素数,同时满足两个条件,或者同时不满足两个条件的数的个数. 析:很明显所有的素数,因数都是2,是素数,所以我们只要算不是素数但因子是素数的数目就好,然 ...

  5. java(2014)实现对mysql数据库分页的代码

    package util; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultS ...

  6. Java Service Wrapper配置详解

    #encoding=UTF-8 # Configuration files must begin with a line specifying the encoding # of the the fi ...

  7. STL中vector容器实现反转(reverse)

    vector容器中实现可以通过以下两种方式实现: #include "stdafx.h" #include <vector> #include <iostream ...

  8. MySQL alter

    1:删除列 ALTER TABLE [表名字] DROP [列名称] 2:增加列 ALTER TABLE [表名字] ADD [列名称] INT NOT NULL  COMMENT '注释说明' 3: ...

  9. Android中全局Application的onCreate多次调用问题

    String processName = OsUtils.getProcessName(this, android.os.Process.myPid()); if (processName != nu ...

  10. HTML5 Web Speech API 结合Ext实现浏览器语音识别以及输入

    简介      Web Speech API是HTML5技术中的一个提供原生语音识别技术的API,Google Chrome在25版之后开始支持Web Speech API,Google也提供了一个 ...