1736. 撲克遊戲 (Standard IO)
Time Limits: 1000 ms Memory Limits: 128000 KB
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.
題解
這是今天做的第四道哈夫曼樹專題了
總結一下
解法大同小異,只是換個方式問而已
類似這道題,題目說得分是 i * j 其實就是哈夫曼樹,模型轉換一下就好了
代碼
#include<iostream>
#include<iostream>
#include<cstdio>
#define INF 2147483647
#define N 20000
using namespace std;
long long dui[N*2+1],top;
void add(long x)
{ long now;
dui[++top]=x;
for(now=top;dui[now/2]>dui[now]&&now>1;now/=2)
swap(dui[now],dui[now/2]);
}
long qu()
{ long ans=dui[1],now;
bool t=false;
dui[1]=INF;
now=1;
while(!t){
t=true;
if(now*2==top||dui[now*2]<dui[now*2+1]){
if(dui[now]>dui[now*2]){
swap(dui[now],dui[now*2]);
now=now*2;
t=false;
}
}else if(now*2+1<=top)
if(dui[now]>dui[now*2+1]){
swap(dui[now],dui[now*2+1]);
now=now*2+1;
t=false;
}
}
return ans;
}
int main()
{ long n,m,i,q;
long long ans=0;
scanf("%ld",&n);
for(i=1;i<=n;i++){
scanf("%ld",&q);
add(q);
}
for(i=1;i<n;i++){
q=qu()+qu();
ans+=q;
add(q);
}
printf("%lld\n",ans);
return 0;
}
ps:
看過我其他博文的有沒有感覺代碼很熟悉
沒錯,就是合併果子