[算法]如何花最少的钱购买蔬菜

如何花最少的钱购买蔬菜

题目地址

题目描述

Description
Rahul wanted to purchase vegetables mainly brinjal, carrot and tomato. There are N different vegetable sellers in a line. Each vegetable seller sells all three vegetable items, but at different prices. Rahul, obsessed by his nature to spend optimally, decided not to purchase same vegetable from adjacent shops. Also, Rahul will purchase exactly one type of vegetable item (only 1 kg) from one shop. Rahul wishes to spend minimum money buying vegetables using this strategy. Help Rahul determine the minimum money he will spend.

Input
First line indicates number of test cases T. Each test case in its first line contains N denoting the number of vegetable sellers in Vegetable Market. Then each of next N lines contains three space separated integers denoting cost of brinjal, carrot and tomato per kg with that particular vegetable seller.

Output
For each test case, output the minimum cost of shopping taking the mentioned conditions into account in a separate line.

Constraints:1 <= T <= 101 <= N <= 100000 Cost of each vegetable(brinjal/carrot/tomato) per kg does not exceed 10^4

Explanation:
There are two ways, each one gives 52 as minimum cost. One way is buy brinjals from first shop, carrots from second shop and brinjals from third shop or he can buy brinjals from first shop, tomatoes from second shop and brinjals from third shop.
Both ways , cost comes up to 1 + 50 + 1 = 52

Sample Input 1

1
3
1 50 50
50 50 50
1 50 50

Sample Output 1

52
题目解析

题目有如下要求

  1. 不从邻近的商店购买同样的蔬菜。
  2. 一家商店购买一种蔬菜
  3. 必须挨着买,即先买第一家,再买第二家
  4. 不是所有的蔬菜都一定需要购买,可以不买某种蔬菜
思路解析

最优问题(最便宜)可以在选完前n-1个的基础上再选第n个,即min(n) = min(n-1) +min(cur)

可以从后往前倒着理解,即在最后一个商店,要么选择了第一种蔬菜,要么选择了第二种蔬菜,要么选择了第三种蔬菜.

假设我们在最后一个商店选了第1种蔬菜,那么在倒数第二个商店同样有三种选择…依次类推

如何构建dp数组

dp数组有几行代表就有几个商店,有几列代表有几个蔬菜,本题有3列.dp[i] [j] 代表当前选到当前商店的当前蔬菜的最少价格

如何更新dp数组
eg

数组更新过程
[[ 1 50 50]  	[[  1  50  50]     [[  1  50  50]
 [ 0  0  0]   	[100  51  51]      [100  51  51]
 [ 0  0  0]]  	[  0   0   0]]     [ 52 101 101]]
 
第二行
100 = min(50,50)+50
51 = min(1,50)+50
第三行
52 = min(100,51)+1
101 = min(100,51)+50
代码实现(python)
if __name__ == '__main__':
    for _ in range(int(input())):
        arr = []
        for _ in range(int(input())):
            temp_arr = list(map(int, input().strip().split()))
            arr.append(temp_arr)
        shop_num = len(arr)
        veg_num = 3
        dp = [[0] * veg_num for _ in range(shop_num)]  # 创建数组
        for i in range(veg_num):  #初始化第一行
            dp[0][i] = arr[0][i]
        for i in range(1, shop_num):
            for j in range(veg_num):  # j=1的话,就去找j=2,j=0  j=2的话,就去找j=0,j=1
                dp[i][j] = min(dp[i - 1][(j + 1) % 3], dp[i - 1][(j + 2) % 3]) + arr[i][j]
        print(min(dp[-1]))
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值