您的位置:首页 > 理论基础 > 计算机网络

西电网络赛 - G

2016-04-17 21:55 573 查看
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
/****************************************************************************************************************
画外音(学神满早上说用贪心,然后想了一天没想出来,晚上打球回来 WC 的时候竟然想出来了)
题意:给定 n 个文件,每次最多合并 k 个文件,输出最小的文件总数
思路:
1,贪贪贪,数值大的文件合并次数尽可能少,尽量多合并数值小的文件。
2,每次合并完之后,将新合并的文件放入原文件堆,重新排序,再次处理

eg:
输入: 7  4
1 2 3 4 5 6 7 8 9 10 11
过程:
1 2 )3 4 5 )6 7 8 )9 10 11    <合并 1 2,花费 1+2=3>
3 3 4 5 )6 7 8 )9 10 11        <合并 3 3 4 5,花费 3+3+4+5=15>
6 7 8 9 )10 11 15               <合并 6 7 8 9,花费 6+7+8+9=30>
10 11 15 30                      <合并 10 11 15 30,花费 10+11+15+30=66>
合并结束,总花费 3+15+30+66=114

****************************************************************************************************************/
int main()
{
int N,M;
long long a[2050];
while(cin>>N>>M)
{
memset(a,0,sizeof(a));
long long sum=0;
for(int i = 1;i <= N;i ++)
cin>>a[i];

sort(a+1,a+N+1);

if(N == 1)
cout<<"0"<<endl;
else if(N <= M){
for(int i = 1;i <= N;i ++)
sum+=a[i];
cout<<sum<<endl;
}
else{

int le=N,mod,id=1;

while(le >  0){

mod=le;
while(mod > M)
mod=mod-(M-1);

long long flag=0;
for(int i = id;i <id+mod;i ++)
flag+=a[i];

id=id+mod-1;
a[id]=flag;
sort(a+id,a+N+1);
sum+=flag;

if(le > mod)
le=le-mod+1;
else
le=0;
}
cout<<sum<<endl;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: