zoukankan      html  css  js  c++  java
  • Proud Merchants---hdu3466(有01背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3466

    与顺序有关的01背包。

    如果一个物品p = 5,q = 7,一个物品p = 5,q = 9,如果先算第一个,那么当次只有7,8...m可以进行状态转移,装第二个物品的时候9,10..m进行转移,第二个物品转移就可以借用第一个物品的那些个状态,而第二个物品先转移,第一个再转移则不能。当然,还有价格有关,当限制一样价格不同时顺序就影响结果。一种组合的排序策略--限制又小价格又贵的先选,也就是q-p小的先选。为什么这样呢?A:p1,q1 B: p2,q2,先选A,则至少需要p1+q2的容量,而先选B则至少需要p2+q1,如果p1+q2>p2+q1,那么要选两个的话的就要先选A再选B,公式可换成q1-p1 > q2-p2,就按这样的方法排序最后的顺序就是最优的顺序。

    该题要确保Q[i]-P[i]小的先被”挑选“,差值越小使用它的价值越大(做出的牺牲越小).

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstdlib>
    using namespace std;
    #define N 510
    #define met(a, b) memset(a, b, sizeof(a))
    
    int dp[N*10], n, m;
    
    struct node
    {
        int v, q, p, qp;
    }a[N];
    int cmp(node p, node q)
    {
        return p.qp<q.qp;
    }
    int main()
    {
        while(scanf("%d %d", &n, &m)!=EOF)
        {
            met(a, 0);
            met(dp, 0);
            for(int i=1; i<=n; i++)
            {
                scanf("%d%d%d", &a[i].p, &a[i].q, &a[i].v);
                a[i].qp = a[i].q - a[i].p;
            }
            sort(a+1, a+n+1, cmp);
            for(int i=1; i<=n; i++)
            {
                for(int j=m; j>=a[i].q; j--)///dp[j]表示剩余j元钱所能购买物品的最大价值;
                    dp[j] = max(dp[j], dp[j-a[i].p]+a[i].v);
            }
            printf("%d
    ", dp[m]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Sharepoint 2010 使用asp.net web应用程序,调试sharepoint程序 解决办法
    sharepoint 管理中心 修改场管理员密码
    Sharepoint 给文档添加评论功能
    Sharepoint 修改评分列数据显示图标的颜色 (等级)
    sharepoint 启用评分功能
    sharepoint 获取术语集源的术语并绑定到下拉列表中
    逆元 板子
    CodeForces
    SPOJ
    [HAOI2011]Problem b 题解
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/4994900.html
Copyright © 2011-2022 走看看