美文网首页
OrderFood 点菜

OrderFood 点菜

作者: sunblog | 来源:发表于2018-04-19 01:12 被阅读0次

Lily 点菜问题 背包问题

题目:

Lily非常喜欢旅游,经常和他老婆自驾出游。但是Lily是一个非常讲求性价比的程序员,所以每次在外面吃饭的时候都要控制价格。今年国庆Lily和他老婆出游,Lily规定每顿饭的价格上限为n,他老婆想点k个菜,餐厅提供m个菜。
请问,在不超过Lily价格上限的情况下,点k个菜有多少种点法(同一种菜只能点一份)。  

 输入:
 1、第一行为价格上限n,想点菜的个数k,以及菜品个数m 
 2、接下来m行,每行一个菜品价格 
 3、以上输入均为正整数  
 输出:
 1、输出为一行,代表点菜的方案数  
 Sample Input:
 10 2 4 
 10 
 3 
 5 
12   
Sample Output:
 1   

(Sample说明:因为需要点两个菜,且总价不超过10,所以只能有第二和第三个菜的组合方案。其他方案加起来都会超过10)

见到的动态规划一般是一维dp[i]和二维的dp[i][j]。没见过三维的,就搞不出来。经过ACM同学的指点,再加一维,就解决了。

为什么再加一维呢,因为这里有k个菜的约束。不像一般的求最大重量那样的问题。

转移方程如下:

// dp[i][j][k] 代表前i个菜,预算刚好为j,选取k个菜的方案总数
// dp[i][j][k] = dp[i-1][j-food[i]][k-1] (food[i]加进去) + dp[i-1][j][k](food[i]不加进去)
// 时间复杂度和空间复杂度都为: O(mnk), m、n、k分别是题目中的数据,分别代表预算,选择个数,菜品总数

具体代码如下:


#ifndef AGORITHM_ORDERFOOD_H
#define AGORITHM_ORDERFOOD_H

#include <vector>
#include <iostream>

using namespace std;

class OrderFood {
public:
    // dp[i][j][k] 代表前i个菜,预算刚好为j,选取k个菜的方案总数
    // dp[i][j][k] = dp[i-1][j-food[i]][k-1] (food[i]加进去) + dp[i-1][j][k](food[i]不加进去)
    // 时间复杂度和空间复杂度都为: O(mnk), m、n、k分别是题目中的数据,分别代表预算,选择个数,菜品总数
    static int answer1(int budget, int tot, std::vector<int> &foods) {
        const int N = foods.size();

        vector<vector<vector<int>>> dp(N, vector<vector<int>>(budget + 1, vector<int>(tot + 1, 0)));

        dp[0][foods[0]][1] = 1;

        for (int i = 1; i < N; i++) {
            for (int j = 1; j <= budget; j++) {
                int prevBudget = j - foods[i];
                for (int k = 1; k <= tot; k++) {
                    if (prevBudget >= 0) {
                        if (prevBudget == 0 && k == 1) {    // new entry
                            dp[i][j][k] += 1;
                        } else {
                            dp[i][j][k] += dp[i - 1][j - foods[i]][k - 1];  // plus previous one
                        }
                    }
                    dp[i][j][k] += dp[i - 1][j][k];
                }
            }
        }


        int count = 0;
        for (int j = 1; j <= budget; j++) {
            count += dp[N - 1][j][tot];
        }

        return count;
    }


    static void test() {
//        int n = 10, k = 2, m = 4;
//        std::vector<int> foods = {10, 3, 5, 12};
        int n, k, m;
        cin >> n >> k >> m;
        std::vector<int> foods(m, 0);
        for (int i = 0; i < m; i++) {
            cin >> foods[i];
        }
        std::cout << "answer: " << answer1(n, k, foods) << endl;
    }
};


#endif //AGORITHM_ORDERFOOD_H

相关文章

  • OrderFood 点菜

    Lily 点菜问题 背包问题 题目: 见到的动态规划一般是一维dp[i]和二维的dp[i][j]。没见过三维的,就...

  • 点菜

    不知道大家有没有跟我一样有“点菜”的困扰,几个朋友的小聚或跟客户一起出去的商务饭局,到点菜的时候就会发怵,不知道要...

  • 点菜

    有一次请朋友吃饭,来到饭馆,朋友一坐下就说,服务员给我们上俩你们店里的硬菜就行了。过了一会,服务员端上来一油炸花玉...

  • 点菜

    文/蝶恋花开蝶恋花 坐在饭桌前的陈默看着锅包肉、春饼、羊腿、红烧肉……口水已经反反复复下咽,最后的矜持和理性控制了...

  • 点菜

    请问要什么辣? 甲:“嗯,中辣吧。” 乙:“要微辣的。” 丙:“嗯,,,我们是北方人,要中辣的!” 丁:“我们要微...

  • 点菜

    看一个人是什么样的人,有一些快捷方式。比如,杀人游戏。还比如,点菜。 你以为点菜是吃货的自然属性?No!只要是吃饭...

  • 点菜

    客官:小二,点菜。 小二:来勒,这位爷,您来点什么? 客官:我要:蒸羊羔、蒸熊掌、蒸鹿尾儿、烧花鸭、烧雏鸡、烧子鹅...

  • 点菜

    别、别说话 给他时间看菜单 他在选好吃的菜品 他在选可承受的平民价 别、别打岔 谁可在餐厅驰骋戎马 他在选常见的食...

  • 点菜

    昨天早上,天哥哥从我买来的一本菜谱书上挑了两个菜让我做。大概每天对付着吃饭,他想吃肉了!小家伙点了一个咖喱鸡块,一...

  • 点菜

    西安出差,出租车驶入城墙门洞时,忽然想起了庄之蝶骑着木兰摩托在此间穿行的样子。印象中,他是孤独的,如同隐居在城市中...

网友评论

      本文标题:OrderFood 点菜

      本文链接:https://www.haomeiwen.com/subject/narikftx.html