SRM399 BinarySum

来源:互联网 发布:美国原油大非农数据 编辑:程序博客网 时间:2024/06/05 16:13

Problem Statement

    

You are given three integers: a, b and c. Convert each of them into their binary representations with no leading zeroes. Let x be the number of binary digits in the longest of the three. Add leading zeroes to the others until all of them have exactly x digits.

Transform a, b and c into a', b' and c', such that a'+b'=c', by optionally reordering the digits within each number. Leading zeroes are allowed. If there are several ways to do this, use the one that minimizes c'.

For example, let a = 7, b = 6 and c = 9. In binary notation, a = 111, b = 110 and c = 1001. We add leading zeroes to a and b so that all of them have exactly four digits: a = 0111, b = 0110, c = 1001. Now, if we reorder the digits within each number to get a' = 0111, b' = 0011 and c' = 1010, we satisfy a' + b' = c' (7 + 3 = 10). There is another way to do this as well (7 + 5 = 12), but this is the way that minimizes c'.

You are given ints a, b and c. Return the minimal possible value of c'. If there is no solution, return -1.

abc(binary)中1的个数固定,求a+b=c组合中c的最小值。

因为固定,所以可以考虑使用abc可使用1的个数做状态。首先是分层,从低位向高位,其次考虑进位,因此有5个状态表示量。

方程是f(n,a,b,c,d)d代表进位。ab各两种取法,决定了c和d。所以计算出f(n-1)最小值*2+c就是当前f(n)的最小值。顺便提一下,vc2005支持64位整数,使用的是longlong,而vc6还不支持。但是vc2005默认开堆栈居然只有1M!害得我莫名其妙stackoverflow了N久。

代码功能暂时挂了,就这样吧。

#define INF  (1e60) #define MAX  (1 << 29)#define MIN  (-MAX) #define INFLL   (10000000000LL)#define MAX_N   (15) #define min(x, y) ( x < y ? x : y )#define max(x, y) ( x > y ? x : y )#define rep(i, n) for ( i = 0; i < n; i ++ ) typedef long long LL;class BinarySum{   LL dp[32][32][32][32][2]; int ones ( int n ) {  return ( n > 0 ? ( n & 1 ) + ones ( n >> 1 ) : 0 ); } int digit ( int n ) {  return ( n > 0 ? 1 + digit ( n >> 1 ) : 0 ); } LL get ( int n, int a, int b, int c, int p ) {   if ( a < 0 || a > n )   return INFLL;  if ( b < 0 || b > n )   return INFLL;  if ( c < 0 || c > n )   return INFLL;  LL &res = dp[n][a][b][c][p];    if ( res != -1 )   return res;  res = INFLL;  if ( n == 0 )  {   if ( a == 0 && b == 0 && c == 0 && p == 0 )    res = 0;   else    res = INFLL;   //printf ( "%d %d %d %d %d %lld/n", n, a, b, c, p, res );   return res;  }  int i, j, k;  rep ( i, 2 ) rep ( j, 2 )  {   k = i + j + p;   LL temp = get ( n - 1, a - i, b - j, c - ( k & 1 ), k >> 1 );   temp = temp * 2 + ( k & 1 );   res = min ( res, temp );  }  //printf ( "%d %d %d %d %d %lld/n", n, a, b, c, p, res );  return res; }public: int rearrange ( int a, int b, int c ) {   int la, lb, lc;  la = ones ( a ), lb = ones ( b ), lc = ones ( c );  int l = max ( max ( digit ( a ), digit ( b ) ), digit ( c ) );  memset ( dp, 0xff, sizeof ( dp ) );  LL res = get ( l, la, lb, lc, 0 );  if ( res == INFLL )   return -1;  else    return int ( res ); }};
 
原创粉丝点击