几道贪心经典题

125. 耍杂技的牛
题解: 我们假设已经排好序好了。
对于第i头牛:sum[i-1] - si => sum[i-1] - si+1
对于第i+1头牛:sum[i] - si+1 => sum[i-1] + wi+1 - si
sum[i-1] + wi - si+1 => sum[i-1] + wi+1 - si
wi+1 + si+1 >= wi + si
那么这样我们就按照 w + s来排序

#include
#define ll long long
using namespace std;
const int maxn = 5e4+10;
struct node
{
    ll w,s;
}a[maxn];
bool cmp(node a,node b)
{
    return a.s+a.w > b.s+b.w;
}
ll sum[maxn];
int main()
{
    int n; cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i].w>>a[i].s;
    sort(a+1,a+1+n,cmp);
    for(int i=1;i<=n;i++) sum[i] = sum[i-1] + a[i].w;
    ll ans = -1e18;
    for(int i=1;i<=n;i++)
    {
        ans =max (ans , sum[n] - sum[i] - a[i].s);
    }
    cout<<ans<<endl;
}

114. 国王游戏
题解:
对于第i个大臣:cheng_l[i-1] / r[i] => cheng_l[i-1] / r[i+1]
对于第i+1个大臣:cheng_l[i] / r[i+1] => cheng_l[i-1] * l[i+1] / r[i]
cheng_l[i-1] * l[i] / r[i+1] => cheng_l[i-1] * l[i+1] / r[i]
l[i] * r[i] >= l[i+1] * r[i+1];
那么我们按照 l * r来排序;
同时学习一下高精度新写法。(学习该站的某位大佬)

#include
using namespace std;
const int maxn = 1e3+10;
struct node
{
    int l,r;
}x[maxn];
bool cmp(node a,node b)
{
    return a.l * a.r < b.l * b.r;
}
vector<int> mul(vector<int>a, int b)
{
    vector<int> c;
    int t = 0;
    for (int i = 0; i < a.size(); i ++ )
    {
        t += a[i] * b;
        c.push_back(t % 10);
        t /= 10;
    }
    while (t)
    {
        c.push_back(t % 10);
        t /= 10;
    }
    return c;
}

vector<int> div(vector<int>a, int b)
{
    vector<int> c;
    bool is_first = true;
    for (int i = a.size() - 1, t = 0; i >= 0; i -- )
    {
        t = t * 10 + a[i];
        int x = t / b;
        if (!is_first || x)
        {
            is_first = false;
            c.push_back(x);
        }
        t %= b;
    }
    reverse(c.begin(), c.end());
    return c;
}

vector<int> max_vec(vector<int> a, vector<int> b)
{
    if (a.size() > b.size()) return a;
    if (a.size() < b.size()) return b;
    if (vector<int>(a.rbegin(), a.rend()) > vector<int>(b.rbegin(), b.rend())) return a;
    return b;
}
int main()
{
    int n ; cin>>n;
    int a,b; cin>>a>>b;
    for(int i=1;i<=n;i++)  cin>>x[i].l>>x[i].r;
    sort(x+1,x+1+n,cmp);
    vector<int> product(1, 1);
    vector<int> res(1, 0);
    product = mul(product,a);
    for(int i=1;i<=n;i++)
    {
      res = max_vec(res,div(product,x[i].r));
      product = mul(product,x[i].l);
    }
    for(int i=res.size()-1;i>=0;i--) cout<<res[i];
    cout<<endl;
}

F 拿物品
题解:
假设物品已经被选完,此时 牛牛选择的物品 A 属性的价值和是 N ; 牛可乐选择的物品 B 属性价值和是 N。
如果 牛牛的 (a1,b1) 物品与 牛可乐的 (a2,b2) 交换。
则N1 = N - a1 + a2 , M1 = M +b1 - b2 ;
对于 牛牛(目标是最大化N - M )来说会变得更优仅当
a1 + b1 < a2 + b2时;
所以按照 a + b 排序。

#include
using namespace std;
const int maxn = 2e5+10;
int a[maxn],b[maxn];
int aa[maxn],bb[maxn];
struct node
{
    int p,id;
}p[maxn];
bool cmp(node a,node b)
{
    return a.p>b.p;
}
int main()
{
    int n; cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) cin>>b[i];
    for(int i=1;i<=n;i++)
    {
        p[i].p = a[i] + b[i];
        p[i].id = i;
    }
    sort(p+1,p+1+n,cmp);
    int c1 = 1 , c2 = 1;
    for(int i=1;i<=n;i++)
    {
        if(i%2) aa[c1++] = p[i].id;
        else bb[c2++] = p[i].id;
    }
    for(int i=1;i<c1;i++) cout<<aa[i]<<" ";
    cout<<endl;
    for(int i=1;i<c2;i++) cout<<bb[i]<<" ";
    cout<<endl;
}

你可能感兴趣的:(贪心)