扑克游戏

Description
  有一棵无穷大的满二叉树,根为star,其余所有点的权值为点到根的距离,如图:
  这里写图片描述
  现在你有一些扑克牌,点数从1到13,你要把这些扑克牌全部放到这个树上:
  1. 当你把点数为i的扑克牌放在权值为j的点上,那么你会得到i*j的分数。
  2. 当你把一个扑克牌放在一个节点上,那么你就不能把别的扑克牌放在这个节点以及这个节点的子树上。
  你的目标是最小化你的得分。

Input
  文件名为 poker.in
  输入第一行为一个数字N,表示你有的扑克牌数;
  接下来一行N个数字,数字在1到13之间。

Output
  文件名为 poker.out
  一个数字,最小得分。

Sample Input
3
5 10 13

Sample Output
43

Data Constraint

Hint
【样例说明】
  这里写图片描述
【数据范围】
  30%数据 N<=100
  100%数据满足1<=N<=10000.
.
.
.
.
.
.

分析

这题听别人讲与哈夫曼树有关
但简化一下
就会发现
这题其实就是类似于
合并果子
.
.
.
.
.

程序:
#include<iostream>
using namespace std;
int n;
long long a[10001];
void kp(int l,int r)
{
    int i,j;
    long long min,g;
    if (l>=r) return;
    i=l;j=r;min=a[(l+r)/2];
    do
    {
        while (a[i]<min) i++;
        while (a[j]>min) j--;
        if (i<=j)
        {
            g=a[i];a[i]=a[j];a[j]=g;
            i++;j--;
        }
    }
    while (i<=j);
    kp(l,j);
    kp(i,r);
}
int main()
{
    int ans,bb,k;
    cin>>n; 
    a[n+1]=2147483647;
    for (int i=1;i<=n;i++)
    cin>>a[i];
    kp(1,n);
    ans=0;
    for (int i=2;i<=n-1;i++)
    {
        a[i]=a[i]+a[i-1];
        ans=ans+a[i];
        for (int j=i+1;j<=n+1;j++)
        if (a[i]<a[j]&&a[i]>=a[j-1])   
        {
            bb=j-1;
            break;
        }
        k=a[i];
        for (int j=i;j<=bb-1;j++)
        a[j]=a[j+1];
        a[bb]=k;
    }
    cout<<ans+a[n-1]+a[n];
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sslgz_yyc/article/details/80945834