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