zoukankan      html  css  js  c++  java
  • HDU-3466-Proud Merchants

    题目链接

    http://acm.hdu.edu.cn/showproblem.php?pid=3466

    这题是个好题,之前没有想到得按先q-p来排序,因为q的原因,取得顺序不好就得不到最大价值。

    看了OceanLight     http://blog.csdn.net/oceanlight/article/details/7866759#comments  的博客

    题意是: 给你一些钱 m ,然后在这个国家买东西, 共有 n 件物品,每件物品有  价格 P    价值 V    还有一个很特别的属性 Q, Q 指 你如过想买这件物品 你的手中至少有这钱Q 。 虽然你只要花费 钱P ,但你的手中至少有钱Q,如果不足Q ,不能买。问给你钱M ,列出N件物品,最多能获得多少价值的东西。。。。

    第一眼看是个DP。。。。  但是想了许久都想不出   状态转移方程。。。

    废话不多说。 给出解题思路。。。。。

    解:    按 Q-P 的大小 ,从小到大排序,然后按照0-1 背包的思想

                                  dp[c]=max(dp[c],dp[c-p[i]])+v[i];  最终 dp[m]就是结果。

    思路很简单,但是很难想。

    在这我给出为什么要按Q-P排序的证明

             一。 首先,不想为什么 ,要按照Q-P  排序。我们先想这么一个问题,(原因一会就知道了)。

               给你n 个这种商品,你最少需要多少钱能够买下来。。(通过这个问题,可以找出一个性质)

                  再把这个商品转化 一下。。

             还是有三个属性  P 价格 、V 价值 、 M 为Q-P

              Sum = P1 +P2 +P3 +........+Pn+max(Mi-(P(i+1)+P(i+2)+...........Pn));

                 要使得Sum 最小 就应该按照 M从大到小排序 (这里就是从大到小,没错),然后0-1背包求解。

             证明:

                 如果看不懂公式 是什么 意思。。。没关系    那你就看 这样一个题的题解。。。这里有相同的公式(很简单的)

             http://blog.csdn.net/oceanlight/article/details/7862104  

             这是我昨天写的一个题的题解,真没想到今天会用到的。。。

             如果你看完了,你就应该懂了 。 要得到最小的sum ,就应该按照  M 从大到小排序了吧

             也就是说我们应该先买M最大的物体,然后买M第二大的 。。。。。  最后买最小的。。。这个性质是这个问题的关键。

            

              二。给一定的钱 ,我们的购买方式是  应该先买M最大的物体(M=Q-P),然后依次买第二大、第三大、、、、、

             我们已经知道这个购买方式,怎么实现就要用到DP  中的0-1背包的思想了。

             dp[c]=max(dp[c],dp[c-p[i]])+v[i];   c 为第c 个物品。这是用一维数组实现01背包。。

             dp[c-p[i]] 是指   我们在容量为c 的包中 放了p[i]之后  还能放的物品的价值。

             i 从 1 到 n  。 dp[c-p[n]]  是放了 第n个物品后 还能放多少价值的物品。。。所以  P[n] 的M 值应该最大

            通俗的说: 这个dp过程 正好是逆向的  。   dp[c-p[i]]是dp[c]的最优子结构。

            所以 在DP 的时候我们应该按照 M的值从小到大排序。

           也就是说我们应该按照 Q-P 的值 从小到 大排序在 DP 了。。。。

    觉得对dp的理解深刻了一点,又感觉对dp不怎么理解了,

    代码

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;

    struct node
    {
    int p,q,v;
    }me[505];

    bool cmp(node a,node b)
    {
    return a.q-a.p<b.q-b.p;
    }

    int main(void)
    {
    int i,j,k,n,m;
    int dp[5005];
    while(scanf("%d%d",&n,&m)==2)
    {
    memset(dp,0,sizeof(dp));
    for(i=0;i<n;i++)
    scanf("%d%d%d",&me[i].p,&me[i].q,&me[i].v);
    sort(me,me+n,cmp);
    for(i=0;i<n;i++)
    {
    for(j=m;j>=me[i].q;j--)
    {
    dp[j]=max(dp[j],dp[j-me[i].p]+me[i].v);
    }
    }
    printf("%d ",dp[m]);
    }
    return 0;
    }

    参数
    62MS 368K 680 B

  • 相关阅读:
    基于水利遥测终端机的山洪灾害水雨情监测解决方案
    水利遥测RTU助力灌区渠道流量监测解决方案
    环保数采仪助力企业智慧用电工况监测系统
    Linq中SingleOrDefault、FirstOrDefault的用法
    private、 protected、 public、 internal 修饰符的访问权限
    Bootstrap 表格
    自我介绍
    周总结
    目前流行的源程序版本管理软件和项目管理软件都有哪些, 各有什么优缺点?
    “模仿”还是“创新”
  • 原文地址:https://www.cnblogs.com/liudehao/p/4106920.html
Copyright © 2011-2022 走看看