写在前面:已经快一年没coding了,所以打算利用这一个月时间进行一个手感的找回,也好为 打下基础

2023.8.6

leetcode 6953

脑筋急转弯,正难则反

leetcode 2813

一开始没想到,看题解后知道是反悔贪心,然后就写了一个错误答案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
class Solution {
public:

struct cmp2{
bool operator()(const pair<int, int> &a, const pair<int, int> &b){
return a.first > b.first;
}
};

pair<int,int> s[100010];
priority_queue< pair<int,int> , vector<pair<int,int> >,cmp2 > p;
int n,tmp=0,lx=0,sum[100010];

static bool cmp1(pair<int,int> a,pair<int,int> b){
if(a.first==b.first) return a.second<b.second;
return a.first>b.first;
}

long long findMaximumElegance(vector<vector<int>>& items, int k) {
n=items.size();

for(int i=1;i<=n;i++){
s[i]=make_pair(items[i-1][0],items[i-1][1]);
}

sort(s+1,s+1+n,cmp1);

for(int i=1;i<=k;i++){
if(sum[s[i].second]==0){
lx++;
sum[s[i].second]=1;
tmp+=s[i].first;
}else{
sum[s[i].second]++;
tmp+=s[i].first;
p.push(make_pair(s[i].first,s[i].second));
}
}

tmp+=lx*lx;

if(p.empty()) return tmp;

for(int i=k+1;i<=n;i++){
if(sum[s[i].second]){continue;}
int tmp1=tmp;
while(!p.empty()&&sum[p.top().second]<=1) p.pop();
if(p.empty()) return tmp;
auto t=p.top();
tmp1-=t.first;
tmp1+=s[i].first;
tmp1-=lx*lx;
tmp1+=(lx+1)*(lx+1);
if(tmp1>tmp){
lx++;
tmp=tmp1;
p.pop();
sum[t.second]--;
sum[s[i].second]++;
}
}

return tmp;
}
};

原谅我的马蜂,意思就是先按利润排序,然后先取前 个,以取前 个这个状态为基准,判断加进来一个会否会使结果变大,如果会那就取,再以这个状态为基准判断下一个,如果不会那就不取,相当于舍弃掉这个东西了

1
items=[[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[3,2],[3,3],[3,4],[3,5],[3,6],[3,7],[3,8],[3,9],[3,10],[3,11]] k=10
1
137

正解是以前 个这个状态为下界,然后尽可能往后取不同类别的东西,答案中类别数的平方使得线性的决策不一定正确,而贪心的思想告诉我们应该尽可能取不同类别的东西,严格来说正解才能称得上是贪心

AGC064A

有点意思的构造题

leetcode 1444

预处理+dp

leetcode 1388

问题转化+环形dp的经典题型,取不相邻的最值,去头去尾分别dp取最值,不然就得存到状态里

ABC315E

建反图统计 的可达点,然后按拓扑序输出

ABC315D

快学英语吧,题都看错了……

ABC315F

向后传递 题,注意不需要跳过太多点,只需要讨论跳过 个以内的点的情况,于是可以把复杂度降到

本文采用CC-BY-SA-3.0协议,转载请注明出处
作者: wsy_jim