Canvas Painting-逆向思维和哈夫曼树

Canvas Painting
After last year’s success, Samuel W. E. R. Craft’s fame continues to grow and now he has funds for all kinds of projects that cross his mind. His newest idea involves creating arrays of canvasses with color patterns having no repeated colors. Samuel bought a set of white canvasses of varying sizes. Since painting them manually would take too much time, he devised a huge machine to automate the painting process. The painting process works as follows:

1. Assemble all canvasses in a line in the machine’s conveyor belt, disposed in some chosen order.

2. Pick a color C and a number F (which should be less than the number of color C canvasses).

3. Going from left to right, all canvasses with color C are painted. The first F color C canvasses are painted with a new color X and the remaining color C canvasses are paintedwithanewcolor Y. Colors X and Y areselectedbythemachine, aredistinct, and are different from any color used previously. The amount of ink spent in this step is equal to the sum of the sizes of the painted canvasses.

4. Repeat 2) and 3) until all canvasses have distinct colors.

Consider for example that Samuel bought four canvasses of sizes 3,5,5and7. Thefollowing picture shows 2 different options for painting them.

 

   

Task

Given the sizes of the canvasses Samuel bought, can you help Samuel finding the minimum amount of ink the machine needs to spend in order to have all canvasses with different colors?

Input

The first line consists of a single integer T, the number of test cases. Each test case is composed by two lines. The first line consists of a single integer N representing the number of canvasses. The next line contains N space separated integers representing the sizes of the canvasses.

Constraints

1 ≤ T ≤ 100 Number of test cases.

1 ≤ Ni ≤ 100000 Number of canvasses in the ith test case.

1 ≤ s ≤ 100000 Size of each canvas.

1 ≤PT i=1 Ni ≤ 100000 Number of canvasses over all test cases in one test file.

Output

The output contains T lines, one for each test case: the minimum amount of ink the machine needs in order to have all canvasses with different colors.

Sample Input
2 3 7 4 7 4 5 3 7 5

Sample Output
29 40
 

题目大意:

初始有n块白布,排列自定,现在每次选择一种存在的颜色C和一个数字F,F<=C的数量,在C中前F块被染成一种weic未出现的颜色X,剩余的C被染成Y色,重复这个步骤直至所有布颜色都不同。

每块布都有一个size,rand染色的代价是每次染色的布的size和,求最小的代价。

正向分配的话很不容易,我们考虑一下这个过程,有一个变成多个不同的,好像并没有一个很好的方法进行划分,但是逆向考虑的话,由n个点合成一个点,想一下哈夫曼树的建树过程,我们可以贪心的选择两个最小的布合成一块在把这两个的size和加进去,这样到最后我们就只得到一个点,这个点就是初始的白布状态。

实现可以考虑优先队列

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int main(void)
{
	priority_queue< LL, vector<LL>, greater<LL> > q;
	int t;
	cin>>t;
	while(t--)
	{
		while(!q.empty()) q.pop();
		LL n,a;
		LL ans;
		cin>>n;
		for(int i=0; i<n; i++)
		{
			scanf("%d",&a);
			q.push(a);
		}
		ans = 0;
        if(n == 1)  //特判一定不要忘,一个元素不可能取出来两个
        {
            cout<<"0"<<endl;
            continue;
        }
		while(!q.empty())
		{
			LL t1=q.top();q.pop();ans+=t1;
			LL t2=q.top();q.pop();ans+=t2;
			if(q.size() != 0)  //没有元素的话就不要加进去了,这时已经合成了
				q.push(t1+t2);
		}
		cout<<ans<<endl;
	}
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值