hdu 2546 - 饭卡

来源:互联网 发布:松下焊接机器人编程 编辑:程序博客网 时间:2024/06/18 02:58

地址

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

定位

  • 动态规划

  • 0-1背包问题变形

  • 分步求解

分析

  • 首先, 判断该问题是0-1背包问题, 理由有二:

    (1) N种菜品, 每种菜品取0、1份。

    (2) 约束条件为不超过总金额, 目标在求菜价最大值

  • 本题较经典0-1背包问题的不同之处:

    (1) 物品重量与价值相同, 每种菜品的花费具有双重属性。

    (2) 目标是获得最少的余额, 等价于求最大的总价值。

    (3) 看似’无限’的背包容量。在整个拾取过程中, ‘无限’最多出现一次, 即最后一次才可能出现’跨越5元’的购买, 或者说一旦’跨越5元’就停止购买。

  • 分二步求解该问题:

    (1) 最后一次购买, 不管能否’跨越5元’, 都应该购买价值最大的物品, 以获取最大的总价值。

    (2) 前若干次购买, 一定不能’跨越5元’, 即 N=n1,V=m5 的0-1背包问题。

代码

#include <stdio.h>#include <stdlib.h>#define MAX_N 1000int value[MAX_N];int dp[MAX_N];int main(){    int m,n;    int i,j,t;    scanf("%d*c",&n);    while(n)    {        memset(value,0,sizeof(value));        memset(dp,0,sizeof(dp));        for(i=1,j=1;i<=n;i++)        {            scanf("%d*c",&value[j]);            if(value[j] > value[0])            {                t = value[j];                value[j] = value[0];                value[0] = t;            }            j++;        }        scanf("%d*c",&m);        if(m >= 5)        {            for(i=value[1];i<=m-5;i++)            {                dp[i] = value[1];            }            for(i=2;i<=n;i++)            {                for(j=m-5;j>=value[i];j--)                {                    dp[j] = dp[j-value[i]] + value[i] > dp[j] ? dp[j-value[i]] + value[i] : dp[j];                }            }            printf("%d\n",m-dp[m-5]-value[0]);        }        else        {            printf("%d\n",m);        }        scanf("%d*c",&n);    }    return 0;}

性能

Exe.Time Exe.Memory Code Length Language 31MS 1420K 1123B c

总结

  • 最大值的分离

    根据解题需求, 应从输入的N维向量中分离出最大值。不仅找到, 还要分离, 涉及到存储变化。

    (1) 排序, 最大值处于首尾, 实现分离, O(nlogn)

    (2) 输入过程中, 边判断边存储, O(n)

Ver 2.0 2017-2-18

0 0
原创粉丝点击