牛客假日团队赛54签到题题解

A-分组

题目描述
在Farmer John最喜欢的节日里,他想要给他的朋友们赠送一些礼物。由于他并不擅长包装礼物,他想要获得他的奶牛们的帮助。你可能能够想到,奶牛们本身也不是很擅长包装礼物,而Farmer John即将得到这一教训。
Farmer John的N头奶牛(1≤N≤10^4) 排成一行,方便起见依次编号为1…N。奶牛i的包装礼物的技能水平为si。她们的技能水平可能参差不齐,所以FJ决定把她的奶牛们分成小组。每一组可以包含任意不超过K头的连续的奶牛(1≤K≤10^3),并且一头奶牛不能属于多于一个小组。由于奶牛们会互相学习,这一组中每一头奶牛的技能水平会变成这一组中水平最高的奶牛的技能水平。

请帮助FJ求出,在他合理地安排分组的情况下,可以达到的技能水平之和的最大值。

输入描述:
输入的第一行包含N和K。以下N行按照N头奶牛的排列顺序依次给出她们的技能水平。技能水平是一个不超过10^5的正整数。

输出描述:
输出FJ通过将连续的奶牛进行分组可以达到的最大技能水平和。

输入
7 3
1
15
7
9
2
5
10
输出
84

说明
在这个例子中,最优的方案是将前三头奶牛和后三头奶牛分别分为一组,中间的奶牛单独成为一组(注意一组的奶牛数量可以小于K)。这样能够有效地将7头奶牛的技能水平提高至15、15、15、9、10、10、10,和为84。

// dp裸题,找到动态转移方程即可
#include <bits/stdc++.h>
#define ll long long 
using namespace std;
int n,k,s[10010],dp[10010]={
    
    0};

int main()
{
    
    
	cin>>n>>k;
	for(int i=1; i<=n; i++) cin>>s[i];
	
	for(int i=1; i<=n; i++) {
    
    
		int m=s[i];
		for(int j=i; j>0&&i-j<k; j--) {
    
    
			m = max(m,s[j]);
			dp[i] = max(dp[i], dp[j-1]+m*(i-j+1));
		}
	}
	cout<<dp[n]<<endl;
	return 0;
}

F-Mixing Milk

题目描述
农业,尤其是生产牛奶,是一个竞争激烈的行业。Farmer John发现如果他不在牛奶生产工艺上有所创新,他的乳制品生意可能就会受到重创!
幸运的是,Farmer John想出了一个好主意。他的三头获奖的乳牛,Bessie、Elsie和Mildred,各自产奶的口味有些许不同,他打算混合这三种牛奶调制出完美的口味。

为了混合这三种不同的牛奶,他拿来三个桶,其中分别装有三头奶牛所产的奶。这些桶可能有不同的容积,也可能并没有完全装满。然后他将桶1的牛奶倒入桶2,然后将桶2中的牛奶倒入桶3,然后将桶3中的牛奶倒入桶1,然后再将桶1的牛奶倒入桶2,如此周期性地操作,共计进行100次(所以第100次操作会是桶1倒入桶2)。当Farmer John将桶aa中的牛奶倒入桶bb时,他会倒出尽可能多的牛奶,直到桶a被倒空或是桶b被倒满。

请告诉Farmer John当他倒了100次之后每个桶里将会有多少牛奶。

输入描述:
输入文件的第一行包含两个空格分隔的整数:第一个桶的容积c1,以及第一个桶里的牛奶量m1。c1和m1均为正,并且不超过10^9。第二和第三行类似地包含第二和第三个桶的容积和牛奶量。

输出描述:
输出三行,给出倒了100次之后每个桶里的牛奶量。

输入
10 3
11 4
12 5
输出
0
10
2

说明
在这个例子中,每倒一次之后每个桶里的牛奶量如下:

初始状态: 3 4 5

  1. 桶1->2: 0 7 5
  2. 桶2->3: 0 0 12
  3. 桶3->1: 10 0 2
  4. 桶1->2: 0 10 2
  5. 桶2->3: 0 0 12
    (之后最后三个状态循环出现……)
#include <bits/stdc++.h>
#define ll long long 
using namespace std;
int i,j,s1,s2,a[4],b[4];

signed main()
{
    
    
	ios::sync_with_stdio(false);
	cin.tie(0);  cout.tie(0);
	for(i=0; i<3; i++)  cin>>a[i]>>b[i];
	 
	for(i=1; i<=100; i++)
	{
    
    
		s1 = (i-1)%3+1; //s1是要将倒出牛奶的桶 
		
		if(s1==3) //桶3给桶1 
			s2=1; //s2是倒入的桶,取桶s2剩余容积和桶s1牛奶数量的最小值 
		
		else  s2=s1+1; //否则给下一个桶 
				
		int minx=min(a[s2]-b[s2],b[s1]); //minx是倒出牛奶的数量
		b[s1]-=minx; //桶s1倒出 
		b[s2]+=minx; //桶s2倒入 
	}
	cout<<b[1]<<endl<<b[2]<<endl<<b[3]<<endl;
	return 0;
}

G-The Bucket List

题目描述
Farmer John正在考虑改变他给奶牛挤奶的时候分配牛奶桶的方式。他认为这最终能使得他使用数量更少的桶,然而他不清楚具体是多少。请帮助他!
Farmer John有N头奶牛(1≤N≤100),方便起见编号为1…N。 第ii头奶牛需要从时间si到时间ti之间挤奶,并且挤奶过程中需要用到bi个桶。于是多头奶牛可能在同一时刻都在挤奶;如果这样,她们不能使用相同的桶。也就是说,一个在第i头奶牛挤奶时用的桶不可以被任何在时间si到时间ti之间挤奶的其他奶牛使用。当然,这个桶在这段时间之外可以被其他奶牛所使用。为了简化他的工作,FJ保证在任一时刻,至多只有一头奶牛开始或是结束挤奶(也就是说,所有的sisi和titi各不相同)。

FJ有一个储藏室,里面有依次编号为1、2、3、……的桶。在他的挤奶策略中,当某一头奶牛(比如说,奶牛i)开始挤奶(在时间si),FJ就跑到储藏室取出编号最小的bi个桶分配给第ii头奶牛用来挤奶。

请求出FJ需要在储藏室中存放多少个桶才能使得他能够顺利地给所有奶牛挤奶。

输入描述:
输入的第一行包含N。以下N行,每行描述了一头奶牛,包含三个空格分隔的数si,ti,和bi。 其中si和ti均为1…1000之间的整数,bi为1…10之间的整数。

输出描述:
输出一个整数,为FJ需要的桶的数量。

示例1
输入
3
4 10 1
8 13 3
2 6 2
输出
4

说明
在这个例子中,FJ需要4个桶:他用桶1和桶2来给奶牛3挤奶(从时间2开始)。他用桶3给奶牛1挤奶(从时间4开始)。当奶牛2在时间8开始挤奶时,桶1和桶2可以再次利用,然而桶3不可以,所以他会使用桶1、桶2和桶4。

洛古大神的各种做法

// 差分做法 
#include <bits/stdc++.h>
using namespace std;
int n,s,t,b,p[1010];

int main() 
{
    
    
	scanf("%d", &n);
	for (int i=1; i<=n; i++) 
	{
    
    
		scanf("%d %d %d", &s,&t,&b);
		p[s-1] += b, p[t] -= b;
	}
	int ans=0, h=0; //h即前缀和
	for (int i=0; i<=1001; i++) 
	{
    
    
		ans = max(ans, h);
		h += p[i];
	}
	cout << ans << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Luoxiaobaia/article/details/108612292