多元haffman编码问题C语言,堆石子游戏的问题(多元Huffman编码)

问题描述:在一个操场的四周摆放着n堆石子。现要将石子有次序地合并成一堆。规定每次至少选2堆最多选k堆石子合并成新的一堆,合并的费用为新的一堆的石子数。试设计一个算法,计算出将n堆石子合并成一堆的最大总费用和最小总费用。编程任务:对于给定n堆石子,编程计算合并成一堆的最大总费用和最小总费用。Input测试数据的第1行有2个正整数n和k,表示有n堆石子,每次至少选2堆最多选k堆石子合并。第2行有n个数,分别表示每堆石子的个数。Output输出最大总费用和最小总费用,用一空格隔开,每个答案一行。

Sample Input

7 3

45 13 12 16 9 5 22

Sample Output

593 199#include

#include

#include

using namespace std;

bool cmp ( int a, int b )

{

return a>b;

}

void Insert ( vector &f, int pos, int value )

{

for ( int i = f.size() - 1; i > pos; i-- )

{

f[i] = f[i - 1];

}

f[pos] = value;

}

int Find ( vector f, int value )

{

int pos = f.size() - 1;

while ( pos >= 0 && f[pos] < value )

{

pos--;

}

return pos + 1;

}

int MaxNum ( vector f )

{

sort ( f.begin(), f.end() );

int Max;

Max = 0;

while ( f.size() >= 2 )

{

int sum = f[f.size() - 1] + f[f.size() - 2];

Max = Max + sum;

f.resize ( f.size() - 1 );

f[f.size() - 1] = sum;

}

return Max;

}

int MinNum ( vector f, int len )

{

sort ( f.begin(), f.end(), cmp );

int Min;

Min = 0;

while ( f.size() >= len )

{

int sum = 0;

for ( int i = f.size() - 1; i >= f.size() - len && i >= 0; i-- )

{

sum = sum + f[i];

}

Min = Min + sum;

f.resize ( f.size() - len + 1 );

if ( f.size() > len )

{

int pos = Find ( f, sum );

Insert ( f, pos, sum );

}

else if ( f.size() != 1 )

{

f[f.size() - 1] = sum;

for ( int i = 0; i < f.size(); i++ )

{

Min = Min + f[i];

}

break;

}

else

{

break;

}

}

return Min;

}

bool run()

{

int n, m;

if ( ! ( cin >> n >> m ) ) return false;

vector f ( n );

for ( int i = 0; i < n; i++ )

{

cin >> f[i];

}

int Max, Min;

Max = MaxNum ( f );

while ( f.size() % ( m - 1 ) != 1 )

{

f.push_back ( 0 );

}

Min = MinNum ( f, m );

cout << Max << " " << Min << endl;

return true;

}

int main()

{

while ( run() );

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值