贪心
1.P2240 【深基12.例1】部分背包问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
算性价比,进行排序来进行局部最优解

1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int t,n; 5 6 struct node 7 { 8 double w,v,p; 9 }a[110]; 10 11 bool cmp(node a,node b) 12 { 13 return a.p > b.p ; 14 } 15 16 int main() 17 { 18 cin >> n >> t; 19 20 for (int i = 1; i <= n; i ++ ) 21 { 22 cin >> a[i].w >> a[i].v; 23 a[i].p = a[i].v / a[i].w; 24 } 25 26 sort(a + 1,a + 1 + n,cmp); 27 28 double sum = 0; 29 for (int i = 1; i <= n; i ++ ) 30 { 31 if(t >= a[i].w) 32 { 33 t -=a[i].w; 34 sum +=a[i].v; 35 } 36 37 else 38 { 39 sum +=a[i].p * (t); 40 break; 41 } 42 } 43 printf("%.2f\n",sum); 44 }
2.P9045 [PA2021] Oranżada - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
把没有出现的品牌尽量往左移,每出现一个新的品牌,我们的品牌数d ++, 我们可以用一个桶来存前s个数字,保证
前s个数字的品牌互不相同,那么我们如果再次出现新的品牌,则从当前位置移到我们的s + 1的位置,同时移的位置
也即为代价,需要的步数,从左往右依次遍历即可
3.Problem - 1760C - Codeforces
求一个数组中除开自己的于最大值的差值,如果开双指针则会超时,我们可以先考虑队数组排序求出数组中的最大值
和次大值,如果该数是数组中的最大值,那么则用最大值减去次大值,如果不是数组中的最大值,则直接用当前数字的值
减去该数组的最大值。

1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N = 2e5 + 5; 4 int n, a[N]; 5 int main() { 6 int t; 7 cin >> t; 8 while(t--) { 9 int max1 = INT_MIN, p, max2 = INT_MIN; 10 cin >> n; 11 for(int i = 1; i <= n; i++) { 12 cin >> a[i]; 13 if(a[i] > max1) { 14 max1 = a[i]; 15 p = i; //找出最大值并作出标记 16 } 17 } 18 for(int i = 1; i <= n; i++) { 19 if(a[i] > max2 && i != p) { 20 max2 = a[i]; //找出次大值 21 } 22 } 23 for(int i = 1; i <= n; i++) { 24 if(i == p) { //如果si为最大值 ,那么用最大值减去次大值 25 cout << a[i] - max2 << ' '; 26 } else { //si不为最大值,直接sI减去最大值 27 cout << a[i] - max1 << ' '; 28 } 29 } 30 puts(""); 31 } 32 return 0; 33 } 34 C++
题意理解: n长度的数组中要有x个a[i] > b[i] ,n - x 个 a[i] <= b[i]
当a数组的后x个最大元素大于 b数组前x小的元素时,这便是最优解

1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int N = 3e5 + 10; 5 6 int t,m,n; 7 int a[N],b[N],c[N],ans[N]; 8 9 int main() 10 { 11 scanf("%d", &t); 12 while(t --) 13 { 14 cin >> n >> m; 15 for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]); 16 for (int i = 1; i <= n; i ++ ) scanf("%d", &b[i]); 17 //对c数组前 1到n 进行赋值 18 iota(c + 1,c + n + 1,1); 19 sort(b + 1,b + n + 1); 20 sort(c + 1,c + n + 1,[](int x, int y){ 21 return a[x] < a[y]; 22 }); //按照a的升序进行排序,c数组表示的a数组的下标 23 24 int ok = 1; 25 for (int i = 1; i <= m; i ++ ) 26 { 27 int x = c[n - m + i]; 28 if(a[x] <= b[i]) ok = 0; //不满足 贪心失败 29 ans[x] = b[i]; //后m个满足a[i] > b[i] 30 } 31 32 for (int i = 1; i <= n - m; i ++ ) 33 { 34 int x = c[i]; 35 if(a[x] > b[m + i]) ok = 0; 36 ans[x] = b[m + i]; //前n - m个满足 a[i] <= b[i]; 37 } 38 39 if(ok){puts("YES"); 40 for (int i = 1; i <= n; i ++ ) cout << ans[i] << " "; 41 cout << endl;} 42 else puts("NO"); 43 } 44 return 0; 45 }
看到 1≤n≤50,1≤k≤100 我们可以想到枚举操作A,B 的次数,计算出结果,取最大值即可。
我们用两层循环枚举 A,B 的次数,计算出 C 的次数。我们取出队列前 A 个和后 B 个,组成新的数组 t,对 t 进行排序,贪心的选择其中的负数执行操作 C。对于 t 中的负数我们从小到大执行操作 C,直到没有负数或者操作数 A + B
C = K

1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 5 const int inf = 0x3f3f3f3f; 6 const int N = 2e5 + 5; 7 8 ll n,k,ans; 9 ll t[N],a[N]; 10 11 int main(){ 12 ios_base::sync_with_stdio(0); 13 cin.tie(0); 14 cin >> n >> k; 15 for (int i = 1; i <= n; i ++ ) cin >> a[i]; 16 17 for (int ia = 0; ia <= k&&ia <= n; ia ++ ) //枚举a的次数 18 for (int ib = 0; ib + ia <= k&&ia + ib <= n; ib ++ ) //枚举b的次数 19 { 20 int cnt = 0; 21 ll sum = 0; 22 for (int i = 1; i <= ia; i ++ ) t[++ cnt] = a[i],sum += a[i]; //加前a个数 23 for (int i = 1; i <= ib; i ++ ) t[++ cnt] = a[n - i + 1],sum += a[n - i + 1];//加后b个数 24 int c = k - ia - ib; //计算c的操作次数(最多) 25 sort(t + 1,t + 1 + cnt); //对选出来的序列进行排序,每次删除最小值直到全为正数或者次数上限 26 for (int i = 1; i <= c && i <= cnt; i ++ ) 27 { 28 if(t[i] > 0) break; 29 sum -= t[i]; 30 } 31 ans = max(ans,sum); 32 } 33 cout << ans << endl; 34 35 }
6.每天所选择的数中,必须满足天数小于剩余天数,在从中找出一个最大的加上即可[ABC137D] Summer Vacation - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

1 #include<bits/stdc++.h> 2 using namespace std; 3 #define endl '\n' 4 #define ll long long 5 #define cy cout << "YES" << endl 6 #define cn cout << "NO" << endl 7 int _,n,m,ans; 8 const int N = 1e5 + 10,inf = 1e9; 9 const int mod = 1e9 + 7; 10 priority_queue<int> q; 11 12 struct node{ 13 int x; 14 int y; 15 }a[N]; 16 17 bool cmp(node a,node b){ 18 return a.x < b.x; 19 } 20 21 int main() 22 { 23 cin >> n >> m; 24 for (int i = 1; i <= n; i ++ ) cin >> a[i].x >> a[i].y; 25 26 sort(a + 1,a + 1 + n,cmp); 27 28 int cnt = 1; 29 for (int i = 1; i <= m; i ++ ){//表示剩余天数 30 for (;a[cnt].x <= i + 1 && cnt <= n; cnt ++ ) q.push(a[cnt].y);//把所有满足条件的插入大根堆 31 if(!q.empty()){ 32 ans += q.top(); 33 q.pop(); 34 } 35 } 36 cout << ans << endl; 37 }