2024.2.22贪心习题(较易)

一、珠宝的最大交替和

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define all(s) s.begin(),s.end()

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int n;cin>>n;
    std::vector<int> a,b;
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        x=abs(x);
        if(i%2) b.push_back(x);
        else a.push_back(x);
    }
    if(n==1)
    {
        cout<<abs(a[0])<<'\n';
    }
    int mini=*min_element(all(a));//对vector中所有元素求和
    int maxi=*max_element(all(b));
    ll ans=accumulate(all(a),0ll)-accumulate(all(b),0ll);
    if(maxi>=mini)ans+=maxi*2-mini*2;
    cout<<ans<<'\n';
    return 0;
}

注意:all(s)的定义,accumulate函数的应用 ,*min_element(all(a));*max_element(all(b));对于vector中的元素如何遍历并取出最大、最小

二、冒险者工会(稍微有点难)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+1;

int main()
{
  int m,n;
  cin>>m>>n;
  std::vector<int> level(m);
  for(int i=0;i<m;i++)
      cin>>level[i];//输入冒险者能力值
  sort(level.begin(),level.end());//进行升序排序,便于后续依此顺序“委派任务”
  std::vector<vector<int>> vill(n,vector<int>(m,0));
  //创建了一个二维的动态数组,类型为int。其中,vill是一个vector容器,它包含了n个元素,每个元素都是一个vector<int>类型的对象。每个vector<int>对象又包含了m个元素,初始值都为0。
  for(int i=0;i<n;i++)
  {
    int k;
    cin>>k;
    if(k>m)
    {
      cout<<-1<<'\n';
      return 0;//如果村庄委派数大于冒险者数量,显然直接是不可能
    }
    for(int j=0;j<k;j++)
    {
      cin>>vill[i][j];
    }
    sort(vill[i].begin(),vill[i].end());//输入村庄数据,并进行升序排序
  }
    std::vector<int> maxi(n+1);//如果把村庄任务难度抽象看作矩阵,村庄为行难度为列,相当于一列最大值开的数组
    for(int i=0;i<m;i++)//这里其实不知道确切的任务数,但可以保证是小于冒险者人数的
    {
      int tra=0;
      for(int j=0;j<n;j++)
      {
        if(vill[j][i]>tra)
        tra=vill[j][i];
      }
      maxi[i]=tra;
    }
    int man=0,cun=0;
    ll ans=0;
    while(cun<m && maxi[cun]==0)
      cun++;
    while(cun<m && man<m)//将任务难度和人数一一比较
    {
      if(maxi[cun]<=level[man])
      {
        cun++;
        ans+=level[man];
      }
      man++;
    }
    if(cun==m)
      cout<<ans<<'\n';
    else
      cout<<-1<<'\n';
  return 0;
}

三、小蓝的礼物

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+9;

int main()
{
   ll n,k;
   cin>>n>>k;
   int a[N];
   for(int i=0;i<n;i++)
   {
     cin>>a[i];
   }
   sort(a,a+n);
   ll sum=0;
   for(int i=0;i<n;i++)
   {
     sum+=a[i];
     if(sum>k)
     {
       sum-=a[i];
       if(a[i]%2)
        a[i]=a[i]/2+1;
      else
        a[i]=a[i]/2;
      sum+=a[i];
      if(sum>k)
      {
      cout<<i<<'\n';
      return 0;
      }
      else
      {
      cout<<i+1<<'\n';
      return 0;
      }
     }
   }
   cout<<n<<'\n';
   return 0;
}

 四、鸡哥的购物挑战

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

int main() {
    ll sp = 0;
    int fumax = -1e9 - 1, zhemin = 1e9 + 1, sum = 0;
    int n; 
    cin >> n;
    for (int i = 0; i < n; i += 1) 
    {
        int x; cin >> x;
        if (x>0) {
            if (zhemin>x) {
                zhemin = x;
            }
            sp += x;
            sum+= 1;
        } else if (fumax < x) {
            fumax = x;
        }
    }
    if (sum % 2)
     {
        sp = max(sp - zhemin, sp + fumax);
     }
    cout << sp << '\n';
    return 0;
}

 贪心这种最优解的问题,最主要的是找到问题的解决方法并转换为代码(找到解决思路可能过程艰难)。当数组很大时,使用vector是个不错的选择。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值