COCI 2006 竞赛 #1 债券任务说明

COCI 2006 Contest#1 Bond task explanation

本文关键字:任务 说明 2006 竞赛 COCI      更新时间:2023-10-16

任务 : http://hsin.hr/coci/archive/2006_2007/contest1_tasks.pdf

我阅读了解决方案,但我不明白此处显示的任何位操作:

/*
  Croatian Open Competition in Informatics 2006/2007
  Contest 1 - Task BOND
  Programming language C++
*/
#include <cstdio>
using namespace std;
int n;
double prob[21][21];
char vec_rijesio[1<<21];
double memo[1<<21];
double rijesi( int d, int s ) {
   if ( d == n )
      return 1.0;
   if ( vec_rijesio[s] ) return memo[s];
   vec_rijesio[s] = 1;
   double &ret = memo[s];
   ret = 0.0;
   for ( int i=0; i<n; ++i )
      if ( ( s & (1<<i) ) == 0 ) {
         double tmp = prob[d][i] * rijesi(d + 1, s|(1<<i));
         if ( tmp > ret ) ret = tmp;
      }
   return ret;
}
int main() {
   scanf( "%d", &n );
   for ( int i=0; i<n; ++i )
      for ( int j=0; j<n; ++j ) {
         int x;
         scanf( "%d", &x );
         prob[i][j] = x / 100.0;
      }
   double ret = rijesi( 0, 0 );
   printf( "%.6fn", ret*100.0 );
   return 0;
}

有人可以为我解释代码吗?1. "1<<21"是什么意思?2. 里杰西()内部的for循环发生了什么?谢谢。

  1. 1<<21 表示 2^21 使用按位左移操作。
  2. 该算法基本上是带有记忆的蛮力,它尝试为给定的吉米债券分配每个任务并检查 结果概率并评估其中的最大值。