leecode每日一练

发布于:2024-05-06 ⋅ 阅读:(32) ⋅ 点赞:(0)

打家劫舍

在这里插入图片描述

我一开始的思路也是dp,但是转移方程想错了,这个题目转移方程应该是dp[i] = max(dp[i-2]+nums[i],dp[i-1])

class Solution {
public:
    int rob(vector<int>& nums) {
        int len = nums.size();
        vector<int> dp(len);
        int ans = 0;
        if(len>=1)
        dp[0] = nums[0],ans=max(ans,dp[0]);
        if(len>=2)
        dp[1] = max(nums[0],nums[1]),ans=max(ans,dp[1]);
        for(int i=2;i<len;i++){
            dp[i] = max(dp[i-2]+nums[i],dp[i-1]);
            ans = max(ans,dp[i]);
        }
        return ans;
    }
};

拆炸弹

在这里插入图片描述
纯模拟就是sb,我用了差分数组,但是转移方程写死我了
我写的代码

class Solution {
public:
    vector<int> decrypt(vector<int>& code, int k) {
        int len = code.size();
        vector<int> ans(len);
        vector<int> p(len+1);
        p[0] = code[0];
        for(int i=1;i<len;i++){
            p[i] = p[i-1]+code[i];
        }
        if(k==0){
            return ans;
        }
        else if(k>0){
            for(int i=0;i<len;i++){
                if(i+k<len){
                    ans[i] += p[i+k]-p[i];
                }else{
                    ans[i] += p[len-1]-p[i];
                    int cha = k-(len-1-i);
                    if(cha>0)
                    ans[i] += p[cha-1];
                }
            }
            
        }else{
            k = -k;
            for(int i=0;i<len;i++){
                if(i>k){
                    if(i-1-k>=0)
                    ans[i] += p[i-1]-p[i-1-k];
                    else{
                        ans[i] += p[i-1];
                    }
                }else{
                    if(i>0)
                    ans[i] += p[i-1];
                    int cha = k-i;
                    ans[i] += p[len-1]-p[len-1-cha];
                }
            }
        }
        return ans;
    }
};

但是其实只要开两倍的空间就可以简单完成,下面这个思路是滑动窗口,但是其实差分也是可以的

class Solution {
public:
    vector<int> decrypt(vector<int>& code, int k) {
        int n = code.size();
        vector<int> res(n);
        if (k == 0) {
            return res;
        }
        code.resize(n * 2);
        copy(code.begin(), code.begin() + n, code.begin() + n);
        int l = k > 0 ? 1 : n + k;
        int r = k > 0 ? k : n - 1;
        int w = 0;
        for (int i = l; i <= r; i++) {
            w += code[i];
        }
        for (int i = 0; i < n; i++) {
            res[i] = w;
            w -= code[l];
            w += code[r + 1];
            l++;
            r++;
        }
        return res;
    }
};

基站建设

题目地址
在这里插入图片描述

一开始我的思路是差分,但是只能过五分之一的数据集,这是因为如果这些重叠的区域过多的话就会出现问题

给你看一下差分的代码

#include<bits/stdc++.h>
using namespace std;

const int N = 1000005;
int s[N];
int p[N];
int n;


int main() {
	cin >> n;
	int a, b;
	int mm = 0;
	for (int i = 1; i <= n; i++) {
		cin >> a >> b;
		int l = (a - b) > 1 ? a - b : 1;
		int r = (a + b) < N ? a + b : N - 1; mm = max(mm, r);
		s[l] += 1;
		s[r + 1] -= 1;
	}
	for (int i = 1; i <= mm; i++) {
		p[i] += p[i - 1] + s[i];
	}
	int re = 0;
	int now;
	int flag = 0;
	for (int i = 1; i <= mm; i++) {
		//cout << p[i] << " ";
		if (flag == 0 && p[i] > 1) {
			flag = 1; // 进入区域
			now = p[i];
		}
		if (flag == 1 && p[i] <= 1) {
			flag = 0; //出去
			re += now - 1;
		}
		if (flag == 1 && p[i] > 1) {
			now = max(now, p[i]);
		}
	}
	cout << n - re;
	return 0;
}

应该用贪心来做,就是一个活动安排问题

#include<bits/stdc++.h>
using namespace std;

const int N = 1000005;
struct node
{
	int start, end;
	bool operator<(node b) {
		return this->end < b.end;
	}
}a[N];

int n;
int main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		int x, b;
		cin >> x >> b;
		a[i].start = x - b;
		a[i].end = x + b;
	}
	sort(a + 1, a + 1 + n);
	if (n == 0) {
		cout << 0;
		return 0;
	}
	int ans = 1;
	int now = a[1].end;
	for (int i = 2; i <= n; i++) {
		if (a[i].start <= now) continue;
		now = a[i].end; ans++;
	}
	cout << ans;
	return 0;
}