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. spring 占位符 默认值

    问题: 今天结合spel使用占位符时,存在没有配置文件中没有配置项的情况,就想给配置一个默认值. 解决方案: public abstract class PlaceholderConfigurerSu ...

  2. HDU 5534 Partial Tree (完全背包变形)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5534 题意: 给你度为1 ~ n - 1节点的权值,让你构造一棵树,使其权值和最大. 思路: 一棵树上 ...

  3. How Tomcat Works(十六)

    本文接下来会介绍Host容器和Engine容器,在tomcat的实际部署中,总是会使用一个Host容器:本文介绍Host接口和Engine接口及其相关类 Host容器是org.apache.catal ...

  4. C# 与 C++ 数据类型对照

    C++            C#=====================================WORD            ushortDWORD            uintUCH ...

  5. opencv win7 配置

    按照官网的配置方法,结果出现了下面的错误信息F:\eclipse C++ workspace\test\Debug/../src/test.cpp:18: undefined reference to ...

  6. My集合框架第四弹 HashTable(链表解决冲突)

    package com.wpr.collection; import java.util.LinkedList; import java.util.List; public class HashTab ...

  7. SQL Server sql 操作

    1.重命名表将表OLD重命名为NEW: EXEC sp_rename 'OLD','NEW' 2.重命名列将表table1中的列old重命名为new: EXEC sp_rename 'table1.o ...

  8. 【tcl脚本】改变输出字符格式

    需求: 原list输出格式 0x00 0x50 0x01 0x03 0x04 0x02 0x21 0x57 0x01 0x00 0x05 0x0B 0x03 0x13 0x00 0x01 要求list ...

  9. Android Service服务

    Service是Android系统中提供的四大组件之一.它是运行在后台的一种服务,一般声明周期较长,不直接与用户进行交互.    服务不能自己运行,需要通过调用Context.startService ...

  10. 转载:Flash AS3.0 加载外部资源(图片,MP3,SWF)的两种方式

    Flash AS3.0 加载外部资源(图片,MP3,SWF)的两种方式 出自:http://www.cnblogs.com/top5/archive/2012/08/04/2623464.html 关 ...