贪心

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 }
Code
复制代码

 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++
Code
复制代码

 4.Problem - C - Codeforces

题意理解: 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 }
Code
复制代码

 5D - equeue (atcoder.jp)

看到 1n50,1k100 我们可以想到枚举操作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 }
Code
复制代码

 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 }
Code
复制代码

 

posted @   rw156  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示