【hdu3080】01背包(容量10^7)
【题意】n个物品,有wi和vi,组成若干个联通块,只能选取一个联通块,问得到m的价值时最小要多少空间(v)。n<=50,v<=10^7
【题解】
先用并查集找出各个联通块。
这题主要就是v太大了,跟以往的背包不同。
我们回想01背包,f[j+v[i]]=max(f[j]+w[i]);
在这里面很明显很多状态都没有用。
优化:如果有2个状态,v1<=v2 && w1>=w2 则(v2,w2)这个状态是没有用的。
我们回到滚动数组中:
f[i][j+v[i]]=max(f[i^1][j]+w[i]);
那么我们可以用两个优先队列,q0存以前的f[i-1],q1存当前的f[i]。
我们在求f[i]的时候,就把q0一个个pop出来,更新后放到q1里面去。
做完i,我们要把q1放到q0,然后做i+1。
在把q1放到q0的时候就把没用的状态去掉(对于(v,val),先按val从大到小排序,再按v从小到大排序,对同样的val取最小的v)。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std; typedef long long LL;
const LL N=,INF=(LL)1e15;
LL n,m,fa[N],t[N],w[N],c[N][N];
struct node{LL v,val;}; struct cmp
{
bool operator () (node &x,node &y)
{
if(x.val==y.val) return x.v<y.v;
return x.val<y.val;
}
}; priority_queue<node,vector<node>,cmp> q0,q1; LL findfa(LL x)
{
if(fa[x]==x) return x;
return findfa(fa[x]);
} LL minn(LL x,LL y){return x<y ? x:y;} int main()
{
freopen("a.in","r",stdin);
freopen("me.out","w",stdout);
int T,cas=;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) fa[i]=i;
for(int i=;i<=n;i++)
{
int num,xx;
scanf("%lld%lld%d",&t[i],&w[i],&num);
for(int j=;j<=num;j++)
{
scanf("%d",&xx);
fa[findfa(i)]=findfa(xx);
}
}
memset(c,,sizeof(c));
for(int i=;i<=n;i++)
{
fa[i]=findfa(i);
c[fa[i]][++c[fa[i]][]]=i;
}
node x,p,f;
LL ans=INF;
for(int k=;k<=n;k++) if(c[k][])
{
// printf("k = %d\n",k);
while(!q0.empty()) q0.pop();
while(!q1.empty()) q1.pop();
x.v=;x.val=;
q0.push(x);
for(int j=;j<=c[k][];j++)
{
int i=c[k][j];
while(!q0.empty())
{
x=q0.top();q0.pop();q1.push(x);
f.v=x.v+t[i];
f.val=x.val+w[i];
if(f.v>=ans) continue;
if(f.val>=m) {ans=minn(ans,f.v);continue;}
q1.push(f);
}
LL mn=INF;
while(!q1.empty())
{
x=q1.top();q1.pop();
if(x.val>=m) ans=minn(ans,x.v);
if(x.v<mn) mn=x.v,q0.push(x);
// printf("v = %lld val = %lld\n",x.v,x.val);
}
}
// f[i^1][v+c[i]]=maxx(f[i^1][v+c[i]],f[i][v]+w[i]]);
}
if(ans<INF) printf("Case %d: %lld\n",++cas,ans);
else printf("Case %d: Poor Magina, you can't save the world all the time!\n",++cas);
}
return ;
}
【hdu3080】01背包(容量10^7)的更多相关文章
- HLOJ1366 Candy Box 动态规划(0-1背包改)
题目描述: 给出N个盒子(N<=100),每个盒子有一定数量的糖果(每个盒子的糖果数<=100),现在有q次查询,每次查询给出两个数k,m,问的是,如果从N个盒子中最多打开k个盒子(意思是 ...
- 2018.08.10 atcoder Median Sum(01背包)
传送门 题意简述:输入一个数组an" role="presentation" style="position: relative;">anan. ...
- HDU 3339 In Action【最短路+01背包模板/主要是建模看谁是容量、价值】
Since 1945, when the first nuclear bomb was exploded by the Manhattan Project team in the US, the n ...
- POJ3211 Washing Clothes[DP 分解 01背包可行性]
Washing Clothes Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 9707 Accepted: 3114 ...
- 【BZOJ-2427】软件安装 Tarjan + 树形01背包
2427: [HAOI2010]软件安装 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 960 Solved: 380[Submit][Status ...
- hdu2546 01背包
http://acm.split.hdu.edu.cn/showproblem.php?pid=2546 01背包问题,首先拿出5元买最贵的东西,那接下来就是背包容量m-5,物品数量n-1 的01背包 ...
- hdu 2955 01背包
http://acm.hdu.edu.cn/showproblem.php?pid=2955 如果认为:1-P是背包的容量,n是物品的个数,sum是所有物品的总价值,条件就是装入背包的物品的体积和不能 ...
- FOJProblem 2214 Knapsack problem(01背包+变性思维)
http://acm.fzu.edu.cn/problem.php?pid=2214 Accept: 4 Submit: 6Time Limit: 3000 mSec Memory Lim ...
- hdu 3466 排序01背包
也是好题,带限制的01背包,先排序,再背包 这题因为涉及到q,所以不能直接就01背包了.因为如果一个物品是5 9,一个物品是5 6,对第一个进行背包的时候只有dp[9],dp[10],…,dp[m], ...
随机推荐
- ReentrantLock类的hasQueuedPredecessors方法和head节点的含义
部分启发来源自文章:Java并发编程--Lock PART 1 1.如果h==t成立,h和t均为null或是同一个具体的节点,无后继节点,返回false.2.如果h!=t成立,head.next是否为 ...
- uwsgi配置文件
[uwsgi] http = :9000 #the local unix socket file than commnuincate to Nginx #socket端口这个用作nginx与其通讯 s ...
- Unity 3d C#和Javascript脚本互相调用 解决方案(非原创、整理资料,并经过实践得来)
Unity 3d C#和Javascript脚本互相调用 解决方案 1.背景知识 脚本的编译过程分四步: 1. 编译所有 ”Standard Assets”, “Pro Standard Assets ...
- 【廖雪峰老师python教程】——装饰器
装饰器 # 一个函数装饰器的列子 def log(func): def wrapper(*args,**kwargs): print('Name=%s'%func.__name__) return f ...
- 关于python的闭包与装饰器的实验
首先看闭包,在嵌套函数内添加返回值,可以通过外部函数读取内部函数信息 #encoding=utf-8 #闭包应用 #先定义闭包函数,并使用 def outer(func): def inner(): ...
- ardupilot_gazebo仿真(四)
ardupilot_gazebo仿真(四) 标签(空格分隔): 未分类 Multi-MAV simulation 参考官网给出的multi-vehicle-simulation的方法 在每次打开sim ...
- Cassandra - Insert after Delete fails silently
在delete一条数据后,再insert 相同内容的数据,结果看起来是成功的,但是当你去查找这个数据,却没有任何内容,整个过程并且没有任何异常提示. 这往往发生在单元测试的时候,我们反复清理和写入数据 ...
- Java开发JDBC连接数据库
Java开发JDBC连接数据库 创建一个以JDBC连接数据库的程序,包含6个步骤: JDBC五部曲1.加载驱动2.获得链接3.获取statement对象 4.执行SQL语句5.产生resultset对 ...
- Spring Boot学习(二):配置文件
目录 前言 方式1:通过配置绑定对象的方式 方式2:@Value("${blog.author}")的形式获取属性值 相关说明 注解@Value的说明 参考 前言 Spring B ...
- Object类中的五种方法
clone() Object类源码:protected native Object clone() throws CloneNotSupportedException; 这里有个问题:为什么Sun公司 ...