贪心专题

本文介绍了如何使用贪心算法解决均分纸牌的问题,给出具体例子N=4,4堆纸牌分别为9,8,17,6,通过3次移动使得每堆纸牌数相等。此外,还涉及牛客网上的贪心题目,讨论如何修复文件碎片以恢复完整歌曲序列,同样应用贪心策略。" 110504939,10329554,Python决策树预测商品购买力,"['机器学习', '数据预处理', '预测模型', 'Python库', '决策树算法']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

T1

P1031 均分纸牌

题目描述

有NN堆纸牌,编号分别为 1,2,…,N1,2,…,N。每堆上有若干张,但纸牌总数必为NN的倍数。可以在任一堆上取若干张纸牌,然后移动。

移牌规则为:在编号为11堆上取的纸牌,只能移到编号为22的堆上;在编号为NN的堆上取的纸牌,只能移到编号为N-1N−1的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。

现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。

例如N=4N=4,44堆纸牌数分别为:

①99②88③1717④66

移动33次可达到目的:

从 ③ 取44张牌放到 ④ (9,8,13,109,8,13,10)-> 从 ③ 取33张牌放到 ②(9,11,10,109,11,10,10)-> 从 ② 取11张牌放到①(10,10,10,1010,10,10,10)。

输入输出格式

输入格式:

 

两行

第一行为:NN(NN 堆纸牌,1 \le N \le 1001≤N≤100)

第二行为:A_1,A_2, … ,A_nA1​,A2​,…,An​ (NN堆纸牌,每堆纸牌初始数,1 \le A_i \le 100001≤Ai​≤10000)

 

输出格式:

 

一行:即所有堆均达到相等时的最少移动次数。

 

输入输出样例

输入样例#1: 复制

4
9 8 17 6

输出样例#1: 复制

3

 

#include <iostream>

using namespace std;
int a[105];
int main()
{
    int n;
    cin >> n;
    int sum = 0,ans = 0;
    for(int i =1 ; i <= n; i++)
    {
        cin>>a[i];
        sum+=a[i];
    }
    ans=sum/n;
    int num=0;
    for(int i=1;i<=n;i++)
    {
        if(a[i]==ans)
            continue;
        else
        {
            a[i+1]+=a[i]-ans;
            num++;
        }
    }
    cout<<num<<endl;
    return 0;
}

华华听月月唱歌(https://ac.nowcoder.com/acm/contest/392/A)

链接:https://ac.nowcoder.com/acm/contest/392/A
来源:牛客网
 

题目描述

月月唱歌超级好听的说!华华听说月月在某个网站发布了自己唱的歌曲,于是把完整的歌曲下载到了U盘里。然而华华不小心把U盘摔了一下,里面的文件摔碎了。月月的歌曲可以看成由1到N的正整数依次排列构成的序列,它现在变成了若干个区间,这些区间可能互相重叠。华华想把它修复为完整的歌曲,也就是找到若干个片段,使他们的并集包含1到N(注意,本题中我们只关注整数,见样例1)。但是华华很懒,所以他想选择最少的区间。请你算出华华最少选择多少个区间。因为华华的U盘受损严重,所以有可能做不到,如果做不到请输出-1。

输入描述:

第一行两个正整数N、M,表示歌曲的原长和片段的个数。
接下来M行,每行两个正整数L、R表示第i的片段对应的区间是[L,R]。

输出描述:

如果可以做到,输出最少需要的片段的数量,否则输出-1。

示例1

输入

复制

4 2
1 2
3 4

输出

复制

2

示例2

输入

复制

4 2
1 1
3 4

输出

复制

-1

示例3

输入

复制

10 5
1 1
2 5
3 6
4 9
8 10

输出

复制

4

备注:

1≤L≤R≤109,1≤N≤109,1≤M≤105


贪心,将所有区间按照左端点排序,从左往右遍历。用一个变量维护我们当前最远可以够到的右端点,然后枚举左端点不超过右端点+1的所有区间,选择右端点最靠右的一个。

 

 

 

#include <iostream>
#include<algorithm>
using namespace std;
struct node
{
    int x;
    int y;
};
const int maxn=1e5+5;
node a[maxn];
bool cmp(node c,node d)
{
    return c.x<d.x;
}
int main()
{
    int n,m;
    cin >> n >> m;
    for(int i=1; i<=m; i++)
    {
        cin >> a[i].x >> a[i].y;
    }
    sort(a+1,a+1+m,cmp);
    int len=1;
 
    int num=0;
    int flag=1;
    while(len<=n)
    {
        int ans=0;
        for(int i=flag;i<=m;i++)
        {
            if(a[i].x<=len)
            {
                ans=max(ans,a[i].y);
            }
            else
            {
                flag=i;
                break;
            }
        }
        if(!ans)
        {
            cout<<-1;
            return 0;
        }
        else
        {
            len=ans+1;
            num++;
        }
    }
        cout<<num<<endl;
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值