pku 1241 Knockout Tournament 树形DP,很好的题目

pku 1241 Knockout Tournament 树形DP,很好的题目

题意:
pku 1241 Knockout Tournament 树形DP,很好的题目_第1张图片
看图说话,一棵锦标赛树(具体不描述,看DS书去),问每个队员的最好名次和最坏名次

分析:
求最好名次应该从上向下划分状态,而求最坏名次从下向上划分状态,举个例子吧,看第三排第一个1,它的最坏名次是第四排第一个1的最坏名次加上它的1^n-右孩子的最坏名次-1,而它的最好名次则是第二排第一个1的最好名次,它旁边那个3的最好名次就是3的父节点(1)的最好名次+1,大概明白什么意思了吧?看代码吧~。

代码:
 1  # include  < cstdio >
 2  # include  < cstring >
 3  using   namespace  std;
 4  # define max(a,b) ((a) > (b) ? (a):(b))
 5  # define min(a,b) ((a) < (b) ? (a):(b))
 6  int  tree[ 1024 ],n;
 7  int  worst[ 1024 ],best[ 1024 ],high[ 1024 ],low[ 1024 ];
 8  int  main()
 9  {
10       while ( true )
11      {
12          scanf( " %d " , & n);
13           if ( ! n)  break ;
14           for ( int  i = 1 << n;i < 1 << (n + 1 );i ++ )
15              tree[i] = 1 + i - ( 1 << n),worst[i] = 1 << n;
16           for ( int  t = n - 1 ;t >= 0 ;t -- )
17               for ( int  i = 1 << t;i < 1 << (t + 1 );i ++ )
18              {
19                   scanf( " %d " ,tree + i);
20                   worst[i] = (tree[i] == tree[i << 1 ] ? worst[i << 1 ] - ( 1 << n) + worst[(i << 1 ) + 1 ]:worst[(i << 1 ) + 1 ] - ( 1 << n) + worst[i << 1 ]) - 1 ;
21              }
22          best[ 1 ] = 1 ;
23           for ( int  i = 2 ;i < 1 << (n + 1 );i ++ )
24              best[i] = (tree[i] == tree[i >> 1 ] ? best[i >> 1 ]:best[i >> 1 ] + 1 );
25           for ( int  i = 1 ;i < 1 << (n + 1 );i ++ )
26              high[i] = low[i] = 1 << n;
27           for ( int  i = 1 ;i < 1 << (n + 1 );i ++ )
28          {
29              high[tree[i]] = min(high[tree[i]],best[i]);
30              low[tree[i]] = min(low[tree[i]],worst[i]);
31          }
32          scanf( " %d " , & n);
33           while (n -- )
34          {
35               int  t;
36              scanf( " %d " , & t);
37              printf( " Player %d can be ranked as high as %d or as low as %d.\n " ,t,high[t],low[t]);
38          }
39          printf( " \n " );
40      }
41       return   0 ;
42  }


你可能感兴趣的:(pku 1241 Knockout Tournament 树形DP,很好的题目)