BZOJ 2427: [HAOI2010]软件安装
来源:互联网 发布:淘宝众筹怎么做 编辑:程序博客网 时间:2024/06/01 07:59
Description
现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi。我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大)。
但是现在有个问题:软件之间存在依赖关系,即软件i只有在安装了软件j(包括软件j的直接或间接依赖)的情况下才能正确工作(软件i依赖软件j)。幸运的是,一个软件最多依赖另外一个软件。如果一个软件不能正常工作,那么它能够发挥的作用为0。
我们现在知道了软件之间的依赖关系:软件i依赖软件Di。现在请你设计出一种方案,安装价值尽量大的软件。一个软件只能被安装一次,如果一个软件没有依赖则Di=0,这时只要这个软件安装了,它就能正常工作。
Solution
这道题蛮好==
首先构图一发。
然后发现有环。
有环的话环可以简单粗暴地看成一个物体。
所以我们先跑一边强联通,然后树形dp
最后分组背包,AC
一开始树形dp敲错了==天生对这种dp有恐惧不知为何。。
想必是儿时收到过心理阴影==
Code
/************************************************************** Problem: 2427 User: bblss123 Language: C++ Result: Accepted Time:120 ms Memory:1512 kb****************************************************************/#include<iostream>#include<string.h>#include<stdio.h>#include<algorithm>#include<vector>#include<stack>using namespace std;const int M=105;int dp[M][M*5],n,m;#define vec vector<int>#define pb push_backvec G[M],edge[M];int wvf[M][3];int sccid[M],pre[M],lowlink[M],allc,dfs_clock;int w[M],val[M],fa[M];stack<int>stk;inline void Min(int &a,int b){if(a>b)a=b;}bool flag[M];bool predfs(int v){ pre[v]=lowlink[v]=++dfs_clock; stk.push(v); flag[v]=1; for(int i=0;i<edge[v].size();++i){ int to=edge[v][i]; if(!pre[to])predfs(to),Min(lowlink[v],lowlink[to]); else if(!sccid[to])Min(lowlink[v],pre[to]); } if(lowlink[v]==pre[v]){ sccid[v]=++allc; for(;!stk.empty();){ int k=stk.top();stk.pop(); sccid[k]=allc; val[allc]+=wvf[k][1]; w[allc]+=wvf[k][0]; if(k==v)break; } }}bool mark[M][M];inline void Graph(){ for(int i=1;i<=n;++i){ int v=sccid[i]; for(int j=0;j<edge[i].size();++j){ int to=sccid[edge[i][j]]; if(to==v)continue; if(!mark[v][to])G[v].pb(to),fa[to]=v; } }}inline void Max(int &a,int b){if(a<b)a=b;}void dfs(int v){ for(int i=0;i<G[v].size();++i) dfs(G[v][i]); int k=m-w[v]; for(int j=0;j<G[v].size();++j){ int to=G[v][j]; for(int i=k;i>=0;--i) for(int l=i;~l;l--) Max(dp[v][i],dp[v][l]+dp[to][i-l]); } for(int i=1;i<=k;++i) Max(dp[v][i],dp[v][i-1]); for(int i=k;i>=0;--i) dp[v][i+w[v]]=dp[v][i]+val[v],dp[v][i]=0;}vec que;int ans[M*5];int main(){ scanf("%d %d",&n,&m); for(int j=0;j<=2;++j) for(int i=1;i<=n;++i){ scanf("%d",&wvf[i][j]); if(j==2&&wvf[i][j])edge[wvf[i][j]].pb(i); } for(int i=1;i<=n;++i) if(!flag[i])predfs(i); Graph(); for(int i=1;i<=allc;++i) if(!fa[i])que.pb(i),dfs(i); for(int i=0;i<que.size();++i){ int v=que[i]; for(int k=m;~k;--k) for(int j=k;~j;--j) Max(ans[k],dp[v][j]+ans[k-j]); }//WA? int res=0; for(int i=0;i<=m;++i) Max(res,ans[i]); printf("%d\n",res); return 0;}
其实跑完强连通以后可以不用树形dp+分组背包,可以直接对节点进行讨论,进行一个类似01背包的dp,这样就可以在最后讨论的时候省掉一个n,况且代码长度也可以大大缩短
因为没有去想所以没想到也是很正常的事情
0 0
- bzoj 2427[HAOI2010] 软件安装
- BZOJ 2427: [HAOI2010]软件安装
- BZOJ 2427: [HAOI2010]软件安装
- 2427: [HAOI2010]软件安装
- BZOJ 2427: [HAOI2010]软件安装|树形动规|tarjan
- |BZOJ 2427|树形DP|强连通分量|[HAOI2010]软件安装
- BZOJ 2427 [HAOI2010]软件安装 Tarjan+树上动态规划
- BZOJ 2427: [HAOI2010]软件安装 Tarjan缩点 + DP
- bzoj 2427: [HAOI2010]软件安装(Trajan+树形DP)
- bzoj 2427: [HAOI2010]软件安装(tarjan缩点+树形dp)
- BOZJ 2427: [HAOI2010]软件安装 树形背包
- bzoj2427: [HAOI2010]软件安装
- 软件安装 [HAOI2010,Bzoj2427]
- BZOJ2427: [HAOI2010]软件安装
- [HAOI2010] 软件安装
- [HAOI2010]软件安装
- [HAOI2010]软件安装
- 【bzoj2427】[HAOI2010]软件安装
- syms使用错误
- Java RMI 简介及其优劣势总结
- react的初始化阶段
- 不是技术牛人,如何拿到国内IT巨头的Offer
- 堆栈程序理解
- BZOJ 2427: [HAOI2010]软件安装
- Android 的内存泄漏
- React Native十五:原生UI组件
- 欢迎使用CSDN-markdown编辑器
- 动态获取时间
- Qt Creator设置代码自动补全
- 贪心算法——Prim最小生成树
- ubuntu中kvm桥接模式设置
- 使用Docker安装HUE