🚀前言 🚀
大家好啊,这里是幸麟
🧩 一名普通的大学牲,最近在学习算法
🧩每日一题的话难度的话是根据博主水平来找的
🧩所以可能难度比较低,以后会慢慢提高难度的
🧩此题标签:greedy sortings *1400(贪心我最近写到的好多啊)
🧩本文栏目:一起来打cf吧
🧩近期更新:codeforces每日一题1-Absolute Sorting_幸麟同学的博客-CSDN博客
期待各位的点赞+收藏+关注,订阅专栏,每天一起写一道cf吧
一起学习算法吧
题目
题目链接:Problem - 1773E - Codeforces
题目:
样例:
题目大意:
Emma喜欢玩积木。她有几个相同大小的积木,上面写着不同的整数(每一个积木上面的数字都是不同的)。她通过垂直堆叠这些积木来组装塔。Emma 可以对塔的配置执行两种操作
1.从塔顶取任意数量的方块并将它们移走,移走的方块会成为一个新的塔
2.将任意两座塔组装在一起,(就是将一座塔的塔底放在另一座塔的塔顶上)
Emma 希望将所有方块堆叠到一个塔中,并且这个塔从顶部到底部是递增的。Emma 希望尽可能少地拆分和组合操作。你的任务是找到她必须进行的最少数量的操作,并输出需要多少次拆分(1操作)和合并(2操作)。
输入
输入文件的第一行包含一个整数 n(初始塔的数量)(1≤n≤10000)
接下来n行分别塔的块数k与从塔顶到塔底的元素
输出
找到最少操作数量后,分别输出1操作与2操作的进行的数量
往下面翻就是答案了(想继续思考的话,还是不要往下面翻了)
答案
首先在得到所有塔的元素之后,我们就可以知道最后的塔是什么样的了,按方块上的数字排就好了
既然我们已经知道了最后塔的样子,那么我们在进行1操作(切割)时就可以避免多余的操作了
我们要求每一座被切割分出去的塔,其中各个元素的相对位置和在最后的塔中的相对位置一致,然后切割出的塔中的元素尽可能的多
一个小栗子:当最后塔的样子是1 2 3 4 5
我们在进行切割的塔的样子4 5 1 2 3
我们可以选择切割成
4
5
1 2 3
这样组合是可以的
但我们最优切法是
4 5
1 2 3
最后进行合并时,合并操作数就是当前塔数-1
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
using namespace std;
const int N=10010;
vector<int>a[N];
int b[N];
int k[N];
unordered_map<int,int> mp;存储最后塔的每个方块的相对位置
int main()
{
int n;
cin>>n;
int t;
int idx=0;
for(int i=0;i<n;i++)
{
scanf("%d",k+i);
for(int j=0;j<k[i];j++)
{
scanf("%d",&t);
a[i].push_back(t);
b[idx++]=t;
}
}
sort(b,b+idx);
for(int i=0;i<idx;i++)
{
mp[b[i]]=i;
}
int tower=n;
for(int i=0;i<n;i++)
{
for(int j=1;j<k[i];j++)
{
if(mp[a[i][j-1]]+1!=mp[a[i][j]])
{
tower++;
}
}
}
cout<<tower-n<<' '<<tower-1;
return 0;
}
好了明天见各位
今天的每日一题就到这里了
关注一波,每日一题cf