第318场力扣周赛 最小移动总距离 --- 记忆化搜索/dp + 数学推导

记忆化搜索写法
class Solution {
public:
	
    long long minimumTotalDistance(vector<int>& a, vector<vector<int>>& fac) {
        sort(a.begin(), a.end());
        sort(fac.begin(), fac.end());
        int n = a.size(), m = fac.size();
    	
        vector<vector<long long>> f(n + 1, vector<long long>(m + 1, 0));
        vector<vector<long long>> d(n + 1, vector<long long>(m + 1, 0));
        
        for(int j = 0; j < m; j ++)
            for(int i = n - 1; i >= 0; i --)
                d[i][j] = d[i + 1][j] + abs(a[i] - fac[j][0]);
        
		function<long long(int,int)> dfs = [&](int i, int j) -> long long
		{
            if(f[i][j]) return f[i][j];
            if(i == n) return 0ll;
			if(j == m - 1)
			{
				if(n - i > fac[j][1]) return 1e18;
				return d[i][j];
			}
			f[i][j] = dfs(i, j + 1);
			long long s = 0, k = 1;
			while(k <= fac[j][1] && i + k - 1 < n)
			{
				s += abs(a[i + k - 1] - fac[j][0]);
				f[i][j] = min(f[i][j], s + dfs(i + k, j + 1));
				k ++;
			}
			return f[i][j];
		};
		return dfs(0, 0);
    }
};
dp写法
class Solution {
public:
    long long minimumTotalDistance(vector<int>&a, vector<vector<int>> &fac) {
        sort(fac.begin(), fac.end());
        sort(a.begin(), a.end());
        int n = a.size();
        vector<long long> f(n + 1, 1e18);
        f[0] = 0;
        for(auto &fa: fac)
            for(int j = n; j > 0; j--) 
            {
                long long cost = 0ll;
                for(int k = 1; k <= min(j, fa[1]); k ++) 
                {
                    cost += abs(a[j - k] - fa[0]);
                    f[j] = min(f[j], f[j - k] + cost);
                }
            }
        return f[n];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_WAWA鱼_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值