吃早饭


私信TA

用户名:dotcpp0721969

访问量:4245

签 名:

等  级
排  名 2424
经  验 2315
参赛次数 0
文章发表 22
年  龄 0
在职情况 学生
学  校
专  业

  自我简介:

TA的其他文章

整体思路:

将现有牌数进行排序,先记录下此时最小牌数min,
那么想要增加一套牌,牌数最小的数字必须加一张手写牌
随后把牌数更新,同时判断后续牌数有没有也是min的;
如果没有就说明本次加入手写牌后整体就增加一套牌
如果有(例如初始牌数都是一样的)那就不急着增加套牌数,对这个牌进行同样的操作

注意事项:开long long
参考代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10; 
ll a[N];//a[i]是指 第i种牌最多能手写 a[i]张 
//利用 multimap 以牌数进行排序,key会出现重复的情况 
multimap<int,int> p;//对组p<某号牌现有的牌数,这组牌的初始下标> 初始下标是为了后续访问a[i] 
ll n,m;
//ans是记录利用手写牌所能增加的套牌数,sum是记录初始时有多少套牌数
//最终的数就是二者之和 
ll ans = 0,sum = 0; 
void way(){//统计ans 
	if(m<=0) return;//已经没有手写牌了,就返回 
	auto bg = p.begin();//bg指向当前最小牌数的pair对组 
	int min = bg->first;//记录最小值方便后续判断是否算得上增加了一套牌 
	int dex = bg->second;//拿到这组牌的初始下标,便于访问a[i]查看他最多能加入几张手写牌 
	if(a[dex]>0){//只有剩余纸张大于0(m>0前面已经判断)且这个号牌还能加入手写牌(a[i]>0) 才加入手写牌 
		a[dex]--;//还能加入的手写牌数减1 
		m--;//总的纸张数减1 
		int temp = min;
		temp++;	//拿到他已有的牌数 加一张手写牌 
		p.erase(bg);//删除原来的数据 
		p.insert(pair<int,int>(temp,dex));//加入现在更新的数据 
		bg = p.begin();//重新让bg指向此时最小数牌的pair对组  
	}
	else {//无法再加入手写牌就返回 
		return;
	}
	if(bg->first!=min) {//现在的最小牌数跟加入手写牌前的最小牌数不同 
		ans++;//增加的这一张手写牌可以让套牌数加1 
	}
	way();//继续上述操作直到无法再加入手写牌 
}
void solve(){
	//数据初始化 
	cin>>n>>m;
	for(int i=0;i<n;i++){
		int j;
		cin>>j;//初始牌数,i为初始下标与a[i]对应 
		p.insert(pair<int,int>(j,i));
	}
	sum = p.begin()->first;//拿到初始的套牌数  就是牌数最少的那个号牌的数量 
	for(int i=0;i<n;i++){
		cin>>a[i];//a[i]记录对应牌的手写牌数量上限 
	}
	way();//统计手写牌的加入能增加几个套牌数---ans 
	cout<<ans + sum;//总套牌数 = 初始套牌数 +  手写牌增加的套牌数
}
int main(){
	solve();
	return 0;
}


 

0.0分

4 人评分

  评论区

  • «
  • »