右端点对齐|镜像复用

lc1648

lc2271

排序瓷砖区间后用滑动窗口,以每个区间右端点为地毯右端,计算窗口内覆盖的最大长度

class Solution {

typedef long long ll;

public:

int maximumWhiteTiles(vector<vector<int>>& tiles, int carpetLen)

{

ll a = 0, s = 0;

int i = 0, l = carpetLen;

sort(tiles.begin(), tiles.end());

for (auto& v : tiles)

{

int L = v[0], R = v[1];

s += (ll)(R - L + 1);

++int cl = R - l + 1;++

while (i < tiles.size() && tiles[i][1] < cl)

{

s -= (ll)(tiles[i][1] - tiles[i][0] + 1);

i++;

}

ll u = 0;

if (i < tiles.size() && tiles[i][0] < cl)

++u = (ll)(cl - tiles[i][0]);++

a = max(a, s - u);

}

return a;

}

};

本质上是窗口内一块一块加毯子,什么情况下缩短窗口呢,毯子盖不到左边毯子的右侧就缩短,开始扯毯子,窗口的大小是多少呢

(我现在已经把整块左侧项的长度都算进来了,而毯子可能只盖到了左侧项的一部分 那么就要减去之前多加进来的长度)

lc3413

镜像翻转 复用代码

先排序硬币区间,用++滑动窗口算正向最大硬币数++

再反转并转换区间方向二次计算,最终取两次结果的最大值。

#include <vector>

#include <algorithm>

using namespace std;

class Solution {

using ll = long long;

ll f(vector<vector<int>>& t, int l) {

ll a = 0, s = 0;

int i = 0;

for (auto& v : t) {

int L = v[0], R = v[1], c = v[2];

s += (ll)(R - L + 1) * c;

int cl = R - l + 1;

while (t[i][1] < cl) {//find ok_l

s -= (ll)(t[i][1] - t[i][0] + 1) * t[i][2];

i++;

}

ll u = max((ll)(cl - t[i][0]) * t[i][2], 0LL);

a = max(a, s - u);

}

return a;

}

public:

ll maximumCoins(vector<vector<int>>& c, int k) {

sort(c.begin(), c.end());

ll a = f(c, k);

reverse(c.begin(), c.end());

for (auto& v : c) {

int tmp = v[0];

v[0] = -v[1];

v[1] = -tmp;

}

return ++max(a, f(c, k));++

}

};

相关推荐
2401_891482176 分钟前
C++代码复杂性分析
开发语言·c++·算法
keep intensify8 分钟前
单词搜索-
算法·深度优先
zx_zx_1238 分钟前
定长滑动窗口和不定长滑动窗口
数据结构·算法
mjhcsp15 分钟前
C++ 梯度下降法(Gradient Descent):数值优化的核心迭代算法
开发语言·c++·算法
yunyun3212322 分钟前
跨语言调用C++接口
开发语言·c++·算法
m0_5180194825 分钟前
C++中的装饰器模式变体
开发语言·c++·算法
xushichao198932 分钟前
高性能密码学库
开发语言·c++·算法
m0_5180194834 分钟前
C++代码混淆与保护
开发语言·c++·算法
m0_5698814737 分钟前
C++中的智能指针详解
开发语言·c++·算法
blackicexs40 分钟前
第九周第三天
算法