100分的答案在这里:http://blog.csdn.net/tigerisland45/article/details/61622152
这道题是一个动态规划的题,寻找最接近中点的两个节点,然后分开,这样,最后,每一个单词总的编码长度是最短的,关键在于理解一个单词编码一次长度加一,然后再与其他单词编码,长度再加一,我这里用到了一个递归的思想,模仿霍夫曼编码,进行了一个模拟,最终结果也是对的,但是只有10分,不是很能想通,留下望日后能够顿悟。
顺便膜一下大佬们,果然是厉害,受教了,希望自己也能快速成长起来。
// 16_12_4.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<algorithm>
using namespace std;
struct code_count {
int num;
string code;
int length;
code_count(int num,string code,int length):num(num),code(code),length(length){
}
} ;
vector<code_count> code;
int sum_vec(vector<int>::iterator t, int n)
{
int sum = 0;
for (int i = 0; i<n; i++)
{
sum += *t;
t++;
}
return sum;
}
void decode(vector<int>::iterator t, int n, string now)
{
if (n == 1)
{
if(now=="")
code.push_back(code_count(*t, "0", 1));
else
{
code.push_back(code_count(*t, now, now.length()));
}
}
else
{
int sum = sum_vec(t, n);
int mid = 1;
for (int i = 2; i<n; i++)
{
float a= abs(sum_vec(t,mid) - sum / 2.0),b= abs(sum_vec(t, i) - sum / 2.0);
if (a > b)
mid = i;
}
string before=now+'0', after=now+'1';
decode(t, mid,before);
decode(t + mid , n-mid, after);
}
}
int main()
{
int n, tmp;
cin >> n;
vector<int> vec(n);
for (int i = 0; i<n; i++)
{
cin >> tmp;
vec[i] = tmp;
}
vector<int>::iterator st = vec.begin();
decode(st, n, "");
vector<code_count>::iterator mst = code.begin();
int size = 0;
while (mst != code.end())
{
size += mst->length*mst->num;
mst++;
}
cout << size;
return 0;
}