[codeforces 1369C] RationalLee 自大到小分配+自少向多分配+不定長數組的使用

Codeforces Round #651 (Div. 2)  參與排名人數14559

[codeforces 1369C]    RationalLee   自大到小分配+自少向多分配+不定長數組的使用

總目錄詳見https://blog.csdn.net/mrcrack/article/details/103564004

在線測評地址http://codeforces.com/contest/1369/problem/C

Problem Lang Verdict Time Memory
C - RationalLee GNU C++17 Accepted 140 ms 10800 KB

題目大意:給定一個數組,將其元素分配到不同的朋友手上,找到每個朋友手上元素的最大值,最小值,求和,尋找一種分配方式,讓其和最大。輸出這個最大和。

樣例解釋如下:

4 2
1 13 7 17
1 3

48
朋友1分配的元素17,最大值是17,最小值是17,和值是17+17=34
朋友2分配的元素1,13,7,最大值是13,最小值是1,和值是13+1=14
最大和值是34+14=48


6 2
10 10 10 10 11 11
3 3

42
朋友1分配的元素11,10,10,最大值是11,最小值是10,和值是11+10=21
朋友2分配的元素11,10,10,最大值是11,最小值是10,和值是11+10=21
最大和值是21+21=42


4 4
1000000000 1000000000 1000000000 1000000000
1 1 1 1

8000000000
朋友1分配的元素1000000000,最大值是1000000000,最小值是1000000000,和值是1000000000+1000000000=2000000000
朋友2分配的元素1000000000,最大值是1000000000,最小值是1000000000,和值是1000000000+1000000000=2000000000
朋友3分配的元素1000000000,最大值是1000000000,最小值是1000000000,和值是1000000000+1000000000=2000000000
朋友4分配的元素1000000000,最大值是1000000000,最小值是1000000000,和值是1000000000+1000000000=2000000000
最大和值是2000000000+2000000000+2000000000+2000000000=8000000000

賽中,第一發WA,想歪了,經過不斷模擬才糾正了想歪的思路,若想看糾正過程,可看AC代碼之後的內容。

基本思路:第一步,將數組元素自大到小排序,將朋友能分配到的元素個數自少到多排序。

兩次分配,第一次,將數組元素自大到小,分配給每個朋友一個元素。

第二次,將剩下的數組元素自大到小,先分配給需求數量少的朋友,充分分配完後,再分配給需求逐漸增多的朋友,直至分配完成。

具體過程如下:

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

55

第一遍分配:
朋友1分配:10
朋友2分配:9
朋友3分配:8
朋友4分配:7

第二遍分配:
朋友1分配:10
朋友2分配:9 6
朋友3分配:8 5 4
朋友4分配:7 3 2 1


朋友1分配:10,最大值是10,最小值是10,和值是10+10=20
朋友2分配:9 6,最大值是9,最小值是6,和值是9+6=15
朋友3分配:8 5 4,最大值是8,最小值是3,和值是8+4=12
朋友4分配:7 3 2 1,最大值是7,最小值是1,和值是7+1=8
最大和值20+15+12+8=55

AC代碼如下:

#include <cstdio>
#include <algorithm>
#include <vector>
#define maxn 200010
#define LL long long
using namespace std;
int a[maxn],w[maxn];
LL ans;
vector<int> q[maxn];
int cmp(int a,int b){
	return a>b;
}
void solve(){
	int n,k,i,cnt,j;
	scanf("%d%d",&n,&k);
	for(i=1;i<=n;i++)scanf("%d",&a[i]);
	for(i=1;i<=k;i++)scanf("%d",&w[i]);
	sort(a+1,a+1+n,cmp);//自大到小排序
	sort(w+1,w+1+k);//自少到多排序
	cnt=0,ans=0;
	for(i=1;i<=k;i++)q[i].clear();
	for(i=1;i<=k;i++)q[i].push_back(a[i]),w[i]--;//第一次分配
	j=k+1;
	for(i=1;i<=k;i++)//第二次分配
		while(w[i])q[i].push_back(a[j]),w[i]--,j++;
	for(i=1;i<=k;i++)
		ans+=q[i][0]+q[i][q[i].size()-1];
	printf("%lld\n",ans);
}
int main(){
	int t;
	scanf("%d",&t);
	while(t--)solve();
}

賽中,第一發WA,想歪了,經過不斷模擬才糾正了想歪的思路,若想看糾正過程,可看AC代碼之後的內容。

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

面對如上數據
朋友1分配:10,最大值是10,最小值是10,和值是10+10=20
朋友2分配:9 6,最大值是9,最小值是6,和值是9+6=15
朋友3分配:8 5 3,最大值是8,最小值是3,和值是8+3=11
朋友4分配:7 4 2 1,最大值是7,最小值是1,和值是7+1=8
最大和值20+15+11+8=54

分配顯然有問題:

面對如上數據,應這樣分配
朋友1分配:10,最大值是10,最小值是10,和值是10+10=20
朋友2分配:9 6,最大值是9,最小值是6,和值是9+6=15
朋友3分配:8 5 4,最大值是8,最小值是3,和值是8+4=12
朋友4分配:7 3 2 1,最大值是7,最小值是1,和值是7+1=8
最大和值20+15+12+8=55

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章