2021-08-23周赛难题恶补

2021-08-26  本文已影响0人  Cipolee

11981. 最小化目标值与所选元素的差

难度中等15 收藏 分享 切换为英文 接收动态 反馈
给你一个大小为 m x n 的整数矩阵 mat 和一个整数 target
从矩阵的 每一行 中选择一个整数,你的目标是 最小化 所有选中元素之 与目标值 target绝对差
返回 最小的绝对差
ab 两数字的 绝对差a - b 的绝对值。

记忆化搜索乃竞赛选手基本技能

我的解(超时)

class Solution:
    def minimizeTheDifference(self, mat: List[List[int]], target: int) -> int:
        min_=[math.inf]
        m,n=len(mat),len(mat[0])
        #isvisited=[False]*m
        #必须使用记忆化搜索,或者使用动态规划
        #动态具有最优化准则
        #使用贪心+剪枝
        dp=[[math.inf]*n for _ in range(m)]
        for i in range(n):
            dp[0][i]=target-mat[0][i]
        for i in range(1,m):
            for j in range(n):
                for jj in range(n):
                    dp[i][j]=dp[i-1][jj]-mat[i][j] if abs(dp[i][j])>abs(dp[i-1][jj]-mat[i][j]) \
                        else dp[i][j]
        min_[0]=min([abs(i) for i in dp[-1]])
        #print(min_[0])
        def dfs(sum_,i):
            if i>=m:
                min_[0]=min(min_[0],abs(target-sum_))
                return 
            for j in range(n):
                try:
                    if sum_+mat[i][j]-target>min_[0]:
                        continue
                    #剪枝也不行
                    dfs(sum_+mat[i][j],i+1)
                except:
                    print(i,j)
        dfs(0,0)
        return min_[0]
class Solution:
    def minimizeTheDifference(self, mat: List[List[int]], target: int) -> int:
        f=set([0])
        m,n=len(mat),len(mat[0])
        for i in range(m):
            g=set()
            for j in f:
                for jj in mat[i]:
                    g.add(j+jj)
            f=g
        ans=math.inf
        for i in f:
            ans=min(ans,abs(i-target))
        return ans
            

*剪枝方案,加和大于target时记录最小的大于target的值,加和小于target时,向set里更新,最后只需要在大于target的最小值与target的差值,与集合与target差值的最小值比较即可。

该题不需要记录求解路径,故不需要搜索算法,而是使用动态规划,结合移位运算,加和可以使用位置表示,加x相当于1左移x

class Solution:
    def minimizeTheDifference(self, mat: List[List[int]], target: int) -> int:
        def to_binary_reversed(x):
            ans=''
            while x:
                ans+=str(x%2)
                x//=2
            return ans
        m,n=len(mat),len(mat[0])
        f=[0]*m
        for j in range(n):
            f[0]|=1<<mat[0][j]
        for i in range(1,m):
            for j in range(n):
                f[i]|=f[i-1]<<mat[i][j]
        move=to_binary_reversed(f[-1])
        ans=math.inf
        for i in range(len(move)):
            if move[i]=='1':
                ans=min(ans,abs(i-target))
        return ans


image.png

待补题与代码

上一篇 下一篇

猜你喜欢

热点阅读