本题要求最远的距离,所有‘_’必须全为左或全为右。利用前缀和的思想看看L多还是R多,最后加上_的数目就是答案。
class Solution { public: int furthestDistanceFromOrigin(string moves) { int n = moves.size(); int tt = 0, lc = 0, rc = 0, tc = 0; for(auto it: moves) { if(it == '_') { tc ++ ; continue; } else if(it == 'L') { lc ++ ; tt -- ; } else { rc ++ ; tt ++ ; } } if(tt == 0) { return tc; } else { return abs(tt) + tc; } } };
一个简单的哈希表
class Solution { public: long long minimumPossibleSum(int n, int target) { long long cnt = 0, sum = 0; unordered_map<int, int> mp; for(int i = 1; ; i ++ ) { if(mp[i]) continue; sum += i, cnt ++ ; if(cnt == n) break; mp[target - i] ++ ; } return sum; } };
若nums的和大于target,由于可以不断除以2会变为1,所以此时一定是有解的。
从二进制的角度看问题,若target的第i位为0,则跳过
若target的第i为为1,则先看<= 2**i的数能否拼出target & mask, 其中mask为(2 ** (i + 1))-1。target&mask表示后i位。若能拼出,则不需要操作。若不 能拼出则找出更大的2的次幂,将其分解为 2 ** i
class Solution: def minOperations(self, nums: List[int], target: int) -> int: if sum(nums) < target: return -1 cnt = Counter(nums) ans = s = i = 0 while 1 << i <= target: s += cnt[1 << i] << i mask = (1 << (i + 1)) - 1 i += 1 if s >= target & mask: continue ans += 1 while cnt[1 << i] == 0: ans += 1 i += 1 return ans
2836. 在传球游戏中最大化函数值
树上倍增算法 = 动态规划 + 二进制枚举、 f[i][j] 表示从第i个点开始,操作 2 ** j次到达的节点中路径的权值和。 节点信息转移方程:f[i][j] = f[f[i][j - 1]][j - 1] 额外信息为: g[i][j] = g[i][j - 1] + g[f[i][j - 1]][j - 1]
class Solution: def getMaxFunctionValue(self, receiver: List[int], k: int) -> int: n = len(receiver) m = k.bit_length() - 1 pa = [[(p, p)] + [None] * m for p in receiver] //这里是记录两维信息 for i in range(m): for x in range(n): p, s = pa[x][i] pp, ss = pa[p][i] pa[x][i + 1] = (pp, s + ss) ans = 0 for i in range(n): x = sum = i for j in range(m + 1): if (k >> j) & 1: x, s = pa[x][j] sum += s ans = max(ans, sum) return ans
标签:周赛,target,int,sum,++,枚举,ans,tt,360 From: https://www.cnblogs.com/zk6696/p/17663431.html