zoukankan      html  css  js  c++  java
  • 加强版金明的预算方案

    题面粘上:

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己与用的很宽敞的房间。
    更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要丌超过
    N 元钱就行”。今天一早,金明就开始做预算了,他把想买的物品分为两类:主件不附件,附件是从属
    于某个件的,下表就是一些主件不附件的例子:
    主件 附件
    电脑 打印机,扫描仪书柜 图书
    书桌 台灯,文具
    工作椅 无
    如果要买归类为附件的物品,必须先买该附件所属的件。每个主件可以有很多个附件。附件可能
    有从属于自己的附件。金明想买的东西很多,肯定会超过妈妈限定的 N 元。于是,他把每件物品规定
    了一个重要度,分为 5 等:用整数 1−5 表示,第 5 等最重要。他还从因特网上查到了每件物品的
    价格(都是在 10 元以内)。他希望在丌超过 N 元(可以等于 N 元)的前提下,使每件物品的价格
    不重要度的乘积的总和最大。
    设第 j 件物品的价格为 v[j] ,重要度为 w[j] ,共选中了 k 件物品,编号依次为 j1,j2,...,jk,则
    所求的总和为:
    v[j1]×w[j1]+v[j2]×w[j2]+...+v[jk]×w[jk]
    请你帮助金明设计一个满足要求的购物单。

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    加强之处:可以有附件的附件(结果我读错了,以为是原题)。

    树形dp,很裸,但是卡常会很厉害,还有O(n^2)的dp很容易写成O(n^3)。

    代码:

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 8050
    
    int n,m;
    int v[N],p[N],hed[N],cnt;
    struct ED
    {
        int to,nxt;
    }e[2*N];
    void ae(int f,int t)
    {
        e[++cnt].to = t;
        e[cnt].nxt = hed[f];
        hed[f] = cnt;
    }
    int dp[N][N];
    int dfs(int u)
    {
        int ret = v[u];
        dp[u][ret]=v[u]*p[u];
        for(int j=hed[u];j;j=e[j].nxt)
        {
            int to = e[j].to;
            int now = dfs(to);
            if(j==hed[u])
            {
                ret += now;
                for(int k = v[u];k<=ret;k++)
                {
                    dp[u][k]=dp[to][k-v[u]]+v[u]*p[u];
                }
            }else
            {
                for(int a = ret;a>=v[u];a--)
                {
                    for(int b = 0;b<=now;b++)
                    {
                        if(a+b>n)break;
                        if(dp[u][a+b]<dp[u][a]+dp[to][b])dp[u][a+b]=dp[u][a]+dp[to][b];
                    }
                }
                ret+=now;
            }
        }
        return ret;
    }
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int q,i=1;i<=m;i++)
        {
            scanf("%d%d%d",&v[i],&p[i],&q);
            ae(q,i);
        }
        dfs(0);
        int ans = 0;
        for(int i=1;i<=n;i++)
        {
            ans = max(ans,dp[0][i]);
        }
        printf("%d
    ",ans);
        fclose(stdin);
        fclose(stdout);
        return 0;
    }

    从dalao那里学来的O(n^2)神奇dfs。

  • 相关阅读:
    FLASH置于底层
    图片等比缩放
    fedora 系统使用 Broadcom BCM4312 无线网卡(转)
    ubuntu语言问题
    轻松安装、卸载Linux软件
    redhat6.0下使用vnc
    http网络安装centos 5.5系统总结
    如何在windows下搭建python的IDE开发环境
    对做技术的一点思考
    C++继承类和基类之间成员函数和虚函数调用机制
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/9580777.html
Copyright © 2011-2022 走看看