【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], ...
随机推荐
- pxe无人值守安装linux机器笔记----摘抄
1. 基建工作 1.关闭防火墙 a)service iptables stop b)service ip6tables stop c)chkconfig iptables off d)chkconfi ...
- 常用操作提高效率 之 for 与in
问题如何而来: 对于刚参加工作的我 批量删除数据通常采用的是前端传递到后台一个对象的id字符串 通过逗号分隔的多个id 或者收的直接是一个id数组 两个原理一样第一个后台要在次使用split(& ...
- 【廖雪峰老师python教程】——OOP
概述 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 数据封装.继承和多态 ...
- Qt Qpushbutton美化问题
昨天在论坛看到一个网友的提问,如下 我想到的第一个就是可能需要重载Pushbutton,不过看到有网友回复可以使用stykesheet解决,今天尝试了一下,还是没有成功, 一下是我使用车重载的Push ...
- Selenium搭配TestNG
用Maven来构建TestNG依赖: <dependency> <groupId>org.testng</groupId> <artifactId>te ...
- 启动 SQL Server 管理 Studio 在 SQL Server 2008R2 中的错误消息:"无法读取此系统上以前注册的服务器的列表" 解决方法
问题: 服务器被人直接停掉,重启后,发现sqlserver2008r2 启动管理器报错: "无法读取此系统上以前注册的服务器的列表" 如图: 点击继续,进入后: 解决方法: 点击上 ...
- Python 异步编程笔记:asyncio
个人笔记,不保证正确. 虽然说看到很多人不看好 asyncio,但是这个东西还是必须学的.. 基于协程的异步,在很多语言中都有,学会了 Python 的,就一通百通. 一.生成器 generator ...
- [leetcode-634-Find the Derangement of An Array]
In combinatorial mathematics, a derangement is a permutation of the elements of a set, such that no ...
- 超像素 superpixels 是什么东西
毕业设计要做图像分割 识别什么的. 看论文看到 superpixels 开始脑补是 像素插值算出来的 后来越看越不想,搜索发现根本是另外一回事 http://blog.sina.com.cn/s/b ...
- 解决ecplise安装mybatipse插件时报找不到jar包的错
在安装mybatipse插件的时候一直报这个错,脑袋疼,在网上搜了半天也没有结果,最后摸索了半天解决了,这里先贴一张图 1.先找到eclipse的安装目录,然后把相应的jar包拷到plugins里去, ...