leetcode
遍历一遍,每次一个变量记录当前几个连续奇数即可。
class Solution {
public:
bool threeConsecutiveOdds(vector& arr) {
int c=0;
for(int i=0;i
观察发现我们最后是把所有数变成 n n n,由于 n n n不大复杂度可以接受,那就遍历到 n n n记录答案,就不搞什么公式了。
class Solution {
public:
int minOperations(int n) {
int ans=0;
for(int i=1;i
二分经典原题,二分答案,check函数要实现的是判断答案是 m i d mid mid时是否可行,只需要遍历一遍vector根据贪心能拿就拿。
class Solution {
int check(int mid,vector v,int m)
{
int pr=v[0];
m--;
for(int i=1;i=mid)
{
m--;
if(m==0)return 1;
pr=v[i];
}
}
return 0;
}
public:
int maxDistance(vector& position, int m) {
sort(position.begin(),position.end());
int l=0,r=1e9+7,ans;
while(l
刚看到就是DP,但是范围太大,接着思考感觉对于吃掉 x x x个橘子连续进行操作一(吃一个)的次数不超过3,那么就是只考虑连续吃若干个后执行操作二,或者操作三(其实就是说如果执行若干操作一后下一步要执行的是操作二或者操作三,都越早执行越好,)。这个“感觉”是对的,一会证明,这里先说下我之前犯的错误,开始编码方法不好,想着多传一个参数表示已经连续执行了多少次操作一,一直WA,发现由于这题范围大需要记忆化,但是如果按多传一个参数的方法第一次求 x x x的时候不一定是最优的,如果直接记录下来会错误。下面证明:
对于当前 x x x,如果执行 k k k次操作一,接下来我要执行操作三(假设 ( x − k ) % 3 = 0 (x-k)\%3=0 (x−k)%3=0),那么就答案就是 d ( ( x − k ) / 3 ) + k + 1 d((x-k)/3)+k+1 d((x−k)/3)+k+1,其中 d ( ( x − k ) / 3 ) d((x-k)/3) d((x−k)/3)表示吃掉 ( x − k ) / 3 (x-k)/3 (x−k)/3个橘子最少的天数,那么如果 k > 3 k>3 k>3,我们有更优的方法:先执行 k − 3 k-3 k−3次操作一,那么答案是 d ( x − k + 3 ) + k − 3 d(x-k+3)+k-3 d(x−k+3)+k−3,对于还剩下的 x − k + 3 x-k+3 x−k+3,因为 ( x − k ) % 3 = 0 (x-k)\%3=0 (x−k)%3=0,所以对于 x − k + 3 x-k+3 x−k+3我们也能执行操作三,就变成 d ( ( x − k ) / 3 + 1 ) + 1 + k − 3 d((x-k)/3+1)+1+k-3 d((x−k)/3+1)+1+k−3,对于 ( x − k ) / 3 + 1 (x-k)/3+1 (x−k)/3+1再执行操作一,答案变成 d ( ( x − k ) / 3 ) + 1 + 1 + k − 3 就 是 d ( ( x − k ) / 3 ) + k − 1 d((x-k)/3)+1+1+k-3 就是d((x-k)/3)+k-1 d((x−k)/3)+1+1+k−3就是d((x−k)/3)+k−1,比之前更优。对于执行 k k k次操作一后执行操作二同理(我们只需先只需 k − 2 k-2 k−2次操作一)。
class Solution {
public:
map mp;
int dfs(int x)
{
if(mp[x])return mp[x];
if(x<=1)return x;
int l=dfs(x/2)+x%2;
int r=dfs(x/3)+x%3;
mp[x]=min(l,r)+1;
return mp[x];
}
int minDays(int n) {
return dfs(n);
}
};