常见的算法题目

常见的算法题目

0-1背包问题:

给定 n 种物品和一个容量为 C 的背包,物品 i 的重量是 w_i,其价值为 v_i 。问:应该如何选择装入背包的物品,使得装入背包中的物品的总价值最大?

分析:

思路1:dp[i][j]表示:在面对第 i 件物品,且背包容量为  j 时所能获得的最大价值 

如果第i个物品不能放进背包,则从前i个物品中选出的最优子集的总价值等于从前i-1个物品中选出的最优子集的总价值。即当j<w_i时,dp[i][j]=dp[i-1][j]

如果第i个物品能放进背包,故需考虑考虑拿这件物品是否能获取更大的价值。如果拿,则:dp[i][j]=dp[i-1][j-w_i]+v_i;如果不拿,则:dp[i][j]=dp[i-1][j]。究竟拿不拿,自然是比较两种情况那种价值最大。

确定的是可能获得的最大价值,但是选取那几件物品能获得最大价值?故需要另外引入一个数组:flag[n],并出初始化为0。即dp[m][c]为最优值。如果dp[m][c]=dp[m-1][c],说明没有取第m件物品。

Weight=list(map(int,input().strip().split()))
Value=list(map(int,input().strip().split()))
totalValue=int(input())
n=len(Value)
dp=[[0 for i in range(totalValue+1)] for j in range(n+1)] 
#range中必须为totalValue+1,即达到包的长度。为n+1,则不用dp的初始化,即选择0个时,价值为0 。
for i in range(1,n+1):
    for j in range(1,totalValue+1):
        if j>=Weight[i-1]:
            # 要把实际意义的下标与程序中的小标对应起来。故为i-1
            dp[i][j]=max(dp[i-1][j],dp[i-1][j-Weight[i-1]]+Value[i-1])
        else:
            dp[i][j]=dp[i-1][j]
flag=[0]*n
def traceBack(n,totalValue):#跟踪那些元素选择
    while n>0:
        if dp[n][totalValue]==dp[n-1][totalValue]:
            flag[n-1]=0
        else:
            flag[n-1]=1
            totalValue-=Weight[n-1]
        n -= 1
    if dp[1][totalValue]>0:
        flag[0]=1
    else:
        flag[0]=0
traceBack(n,totalValue)
print(dp[n][totalValue])
print(flag)

思路2:dp[j]表示容量为j的情况下获得最优的价值。如果第i个物品放入背包中,则dp[j]=d[j-w_i]+v_i;若第i个物品没有放入背包中,则:dp[j]=dp[j];究竟放不放,自然是比较两种情况那种价值最大。

Weight=list(map(int,input().strip().split()))
Value=list(map(int,input().strip().split()))
totalValue=int(input())
n=len(Value)
dp=[0]*(totalValue+1)
for i in range(n):
    j=totalValue
    while j>=Weight[i]:
        dp[j]=max(dp[j],dp[j-Weight[i]]+Value[i])
        j-=1
print(dp[totalValue])

0-1背包的变形题目

关键的时如何把最小问题转为最大问题:充分利用哪个量在程序中是不变的量,利用运算规则,与不变量建立关系。从而解决问题的求解。

  • 一种双核CPU的两个核能够同时的处理任务,现在有n个已知数据量的任务需要交给CPU处理,假设已知CPU的每个核1秒可以处理1kb,每个核同时只能处理一项任务。n个任务可以按照任意顺序放入CPU进行处理,现在需要设计一个方案让CPU处理完这批任务所需的时间最少,求这个最小的时间。

分析:完成所有n个任务需要sum时间,放入两个cpu中执行,假设第一个cpu处理时间为n1,第二个cpu时间为sum-n1,并假设n1 <= sum/2,sum-n1 >= sum/2,要使处理时间最小,则n1越来越靠近sum/2,最终目标是求max(n1,sum-n1)的最大值。转换为01背包问题:已知最大容纳时间为sum/2,有n个任务,每个任务有其的完成时间,求最大完成时间。

  • 满减优惠问题:近天气炎热,小红天天宅在家里叫外卖。他常吃的一家餐馆一共有N道菜品,价格分别是A_1,A_2,\dots,A_N元。并且如果消费总计满X元,还能享受优惠。他希望选择若干道不同的菜品,使得总价在不低于X元的同时尽量低。你能算出这一餐小红最少消费多少元吗?

分析:先获取总额sum,得到sum与x的差值,再看这个差值是否能变到最大。

你可能感兴趣的:(Algorithm)