zoukankan      html  css  js  c++  java
  • beibao

    解题思路:本题为动态规划题目,用01背包即可解决。

            其实本题一眼看去像是贪心的题目,但是用贪心解却是错的,因为每个菜式的价钱一定,不可分隔。若用贪心,可能买了教贵的菜,剩下的钱不能买任意菜式,买某些便宜的菜,又使得贵的菜拉掉,最终不能最大限度的使用m-5元钱。

           首先 ,按要求输入一组数据,输入完后判断是否能购买物品(m>=5?),若不能再购买物品,则直接输出m即可。

           然后 ,现有金额可以购买物品,先对所有菜式的价格由小到大排序,等下动归处理时,不处理贵的菜(c[n-1]),留到最后还有5元时才购买,以求剩下的钱最少。对于dp[j]数组,用于求还剩j元可以使用时(j<=m-5)可以消费的最大金额,一律初始化为0。

           然后 ,对于动态转移方程:

    (1) dp[j]=dp[j]>(dp[j-c[i]]+c[i])?dp[j]:(dp[j-c[i]]+c[i]); //剩下j元时,可消费的最大金额

    (2) 其原型为:

    dp[i][j]=max{dp[i-1][j],(dp[i-1][j-c[i]]+c[i])}; //对于第i种菜品,剩下j元时,可消费的最大金额(买或不买第i种菜品)

    (3) 其意思是:(对于第i种菜品而言,剩下j元可以消费时,可消费的最大金额)=max{

       【 (对于第i-1种菜品而言,剩下j元可以消费时,可消费的最大金额) (不买第i种菜品)】,

        【 ((对于第i-1种菜品而言,剩下j-c[i]元可以消费时,可消费的最大金额 )+购买第i种菜品需消费的金额)(买第i种菜品) 】

    }

    (4) 用滚动数组做动态规划处理 dp[j]=max(dp[j],(dp[j-c[i]]+c[i])),(j=m-5;j>=c[i];j--)当处理第i种菜品时

    dp[j],dp[j-c[i]]存储的数据就是 dp[i-1][j],dp[i-1][j-c[i]],所以,没必要使用二维数组,可节约程序运行时的内存,每当i改变时,dp[]数组即被更新,最后答案存储在dp[m-5]中。

          

    最后 ,输出饭卡种剩下的最少的金额即可。

    饭卡种剩下的最少的金额 =m-dp[m-5]-c[n-1](总金额-除保底5元外所能使用的最多得金额-用最后至少5元消费的最贵的菜品)。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    int main()
    {
        int n;
        int m;
        int i,j;
        int c[1002],dp[1002];  //菜品i的价钱,有i元钱时,最多可以用用多少
        while(scanf("%d",&n)&&n)
        {
            for(i=0;i<n;i++)
                scanf("%d",&c[i]);
            scanf("%d",&m);
            if(m<5)    //若总金额小于5,不能购买东西
            {
                printf("%d
    ",m);
                continue;
            }
            sort(c,c+n);  //排序后,最后一个不处理,最大面额的菜留到最后5元时买
            memset(dp,0,sizeof(dp));  //初始化
            for(i=0;i<n-1;i++)    //i<n-1,留下最大面额的菜不做处理
                for(j=m-5;j>=c[i];j--)   //j=m-5,留下最后5元用来购买最贵的菜
                    dp[j]=dp[j]>(dp[j-c[i]]+c[i])?dp[j]:(dp[j-c[i]]+c[i]);   //剩下j元时,可消费的最大金额
            printf("%d
    ",m-dp[m-5]-c[n-1]);  //剩下的最小金额=总金额-至少留5元所能消耗的最大金额-最贵的菜的金额
        }
        return 0;
    }

     

  • 相关阅读:
    BZOJ1527 : [POI2005]Pun-point
    2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016)
    2016-2017 ACM-ICPC Northwestern European Regional Programming Contest (NWERC 2016)
    NAIPC-2016
    BZOJ2498 : Xavier is Learning to Count
    ACM ICPC Vietnam National Second Round
    XVI Open Cup named after E.V. Pankratiev. GP of Ukraine
    XVI Open Cup named after E.V. Pankratiev. GP of Peterhof
    HDU5509 : Pattern String
    BZOJ4583 : 购物
  • 原文地址:https://www.cnblogs.com/luzhongshan/p/3889551.html
Copyright © 2011-2022 走看看