POJ1694 An Old Stone Game (树,排序) .

An Old Stone Game


这道题看了好几遍,又看了看别人给的数据才看明白。意思就是现在有一棵树,有一些石头,依次把石头放在树叶上,如果一个节点的叶子节点全有一个石头了,就可以把它们的石头去掉,并把其中的一个石头放在这个节点上,而这个结点就相当于一个叶子节点了,去掉的石头可以再用,问直到根节点上放了石头,一共要多少石头。

对树的存法不太清楚,怎么做也没明白。上网找到一篇解题报告 ,看了一会明白了。

其实不是很难。想算一个节点所需要的石头(为了避免麻烦,就从根结点开始),如果没有子结点了,那只需要一个石头就够了,如果有,就分别算出每个子节点所要的石头,然后就是最重要的步骤。

把它们从大到小排序,a1 - an,现在想如果a1 > a2 > ... > an的话,处理完1要用去a1个石头,留下了一个剩a1-1个,而a1 > a2,所以a1-1 >= a2,所以2就不用额外的石头了,同理到an也不再需要额外的石头。

那什么情况需要呢,例如 a1 = 4, a2 = 4, a3 = 3,那1剩下的石头不够2用,就要再加一个,也就是i需要ai再加上前边放好的石头,当然放石头什么顺序都行,而且结果是一样的,就可以从大到小排序,从大到小放,i就需要ai+i-1个,最大 需求 的就是父节点的需求。

 

#include <iostream>
#include <algorithm>
using namespace std;
int tree[201][201];
int solve(int x)
{
 int i;
 if (tree[x][0] == 0)
  return 1;
 int tmp[201];
 for (i=1; i <= tree[x][0]; i++)
 {
  tmp[i-1] = solve(tree[x][i]);
 }
 sort(tmp, tmp+tree[x][0]);
 for (i=0; i < tree[x][0]; i++)
  tmp[i] += tree[x][0] - i - 1;
 //返回tmp数组中最大的元素
 return *max_element(tmp, tmp + tree[x][0]);
}
int main()
{
 int M,i,j;
 cin>>M;
 while (M--)
 {
  memset(tree, 0, sizeof(tree));
  int N;
  cin>>N;
  for (i=1; i <= N; i++)
  {
   cin>>tree[i][0]>>tree[i][0];
   for (j=1; j <= tree[i][0]; j++)
    cin>>tree[i][j];
  }
  cout<<solve(1)<<endl;
 }
 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值