• 洛谷——P2515 [HAOI2010]软件安装


    https://www.luogu.org/problem/show?pid=2515#sub

    题目描述

    现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi。我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大)。

    但是现在有个问题:软件之间存在依赖关系,即软件i只有在安装了软件j(包括软件j的直接或间接依赖)的情况下才能正确工作(软件i依赖软件j)。幸运的是,一个软件最多依赖另外一个软件。如果一个软件不能正常工作,那么它能够发挥的作用为0。

    我们现在知道了软件之间的依赖关系:软件i依赖软件Di。现在请你设计出一种方案,安装价值尽量大的软件。一个软件只能被安装一次,如果一个软件没有依赖则Di=0,这时只要这个软件安装了,它就能正常工作。

    输入输出格式

    输入格式:

    第1行:N, M (0<=N<=100, 0<=M<=500)

    第2行:W1, W2, ... Wi, ..., Wn (0<=Wi<=M )

    第3行:V1, V2, ..., Vi, ..., Vn (0<=Vi<=1000 )

    第4行:D1, D2, ..., Di, ..., Dn (0<=Di<=N, Di≠i )

    输出格式:

    一个整数,代表最大价值

    输入输出样例

    输入样例#1:
    3 10
    5 5 6
    2 3 4
    0 1 1
    输出样例#1:
    5


    f[u][i]表示安装u占用i的内存能得到的最大价值
      1 #include <algorithm>
      2 #include <cstdio>
      3 
      4 using namespace std;
      5 
      6 const int N(119);
      7 const int M(555);
      8 int n,m,w[N],v[N],f[N][M];
      9 
     10 int hed[N],had[N],sumedge;
     11 struct Edge
     12 {
     13     int v,next;
     14     Edge(int v=0,int next=0):
     15         v(v),next(next){}
     16 }edge[M<<1];
     17 void ins(int u,int v,int *head)
     18 {
     19     edge[++sumedge]=Edge(v,head[u]);
     20     head[u]=sumedge;
     21 }
     22 
     23 int tim,dfn[N],low[N];
     24 int Stack[N],instack[N],top;
     25 int sumcol,col[N],cval[N],cw[N];
     26 void DFS(int now)
     27 {
     28     dfn[now]=low[now]=++tim;
     29     Stack[++top]=now; instack[now]=1;
     30     for(int i=hed[now];i;i=edge[i].next)
     31     {
     32         int v=edge[i].v;
     33         if(!dfn[v]) DFS(v),low[now]=min(low[now],low[v]);
     34         else if(instack[v]) low[now]=min(low[now],dfn[v]);
     35     }
     36     if(low[now]==dfn[now])
     37     {
     38         col[now]=++sumcol;
     39         cw[sumcol]+=w[now];
     40         cval[sumcol]+=v[now];
     41         for(;now!=Stack[top];top--)
     42         {
     43             col[Stack[top]]=sumcol;
     44             cw[sumcol]+=w[Stack[top]];
     45             cval[sumcol]+=v[Stack[top]];
     46             instack[Stack[top]]=0;
     47         }
     48         instack[now]=0;top--;
     49     }
     50 }
     51 
     52 int dad[N],root;
     53 void Get_tree()
     54 {
     55     for(int i=1;i<=n;i++)
     56         for(int j=hed[i];j;j=edge[j].next)
     57         {
     58             if(col[i]==col[edge[j].v]) continue;
     59             dad[col[edge[j].v]]=col[i];
     60             ins(col[i],col[edge[j].v],had);
     61         }
     62 }
     63 void DP(int x)
     64 {
     65     for(int i=had[x];i;i=edge[i].next)
     66     {
     67         DP(edge[i].v);
     68         for(int j=m-cw[x];j>=0;j--)
     69           for(int k=0;k<=j;k++)
     70             f[x][j]=max(f[x][j],f[x][k]+f[edge[i].v][j-k]);
     71     }
     72     for(int i=m;i>=0;i--)
     73     {
     74         if(i>=cw[x]) f[x][i]=f[x][i-cw[x]]+cval[x];
     75         else f[x][i]=0;
     76     }
     77 }
     78 
     79 int main()
     80 {
     81 //    freopen("install.in","r",stdin);
     82 //    freopen("install.out","w",stdout);
     83     scanf("%d%d",&n,&m);
     84     for(int i=1;i<=n;i++) scanf("%d",w+i);
     85     for(int i=1;i<=n;i++) scanf("%d",v+i);
     86     for(int i=1,x;i<=n;i++)
     87     {
     88         scanf("%d",&x);
     89         if(x) ins(x,i,hed);
     90     }
     91     for(int i=1;i<=n;i++)
     92         if(!dfn[i]) DFS(i);
     93     Get_tree();
     94     for(int i=1;i<=sumcol;i++)
     95         if(!dad[i])
     96         {
     97             dad[i]=1;
     98             ins(sumcol+1,i,had);
     99         }
    100     DP(sumcol+1);
    101     printf("%d",f[sumcol+1][m]);
    102     return 0;
    103 }
    ——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。
  • 相关阅读:
    用jQuery写的一个简单的弹出窗口(IE7\IE8\FF3)
    live write test
    sql2
    查询所有表索引
    java初学问题记录(2012.02.092012.02.16)
    SQL
    centso7网卡bond
    vmware模板
    Dockerfile参考
    Docker简单介绍
  • 原文地址:https://www.cnblogs.com/Shy-key/p/7194252.html
Copyright © 2020-2023  润新知