UVa 714 - Copying Books

最大值最小化问题,二分+贪心,参考刘汝佳白皮书151页。

之前我的代码在UVa上交过了,但是在ZOJ上却是WA。

后来才发现是错在这两组数据:

2

4 3

100000 1 1 1

4 3

1 1 1 100000

  1 #include <cstdio>

  2 #include <cstring>

  3 

  4 const int MAXN = 1000 + 10;

  5 

  6 int m,k;

  7 long long int num[MAXN];

  8 long long int sum;

  9 bool w[MAXN];

 10 

 11 bool Judge( long long int x )

 12 {

 13     int count = 0;

 14     long long int temp = 0;

 15     long long int temp2 = 0;

 16     for ( int i = 0; i < m; )

 17     {

 18         temp += num[i];

 19         if ( temp <= x ) i++;

 20         else

 21         {

 22             temp2 = temp;

 23             temp = 0;

 24             count++;

 25             if ( count > k ) return false;

 26         }

 27     }

 28 

 29     if ( temp2 != 0 ) count++;

 30 

 31     if ( count > k ) return false;

 32     else return true;

 33 }

 34 

 35 long long int Bsearch( long long int x, long long int y )

 36 {

 37     long long int m;

 38 

 39     while ( x < y )

 40     {

 41         m = x + (y - x) / 2;

 42         if ( Judge(m) ) y = m;

 43         else x = m + 1;

 44     }

 45     return y;

 46 }

 47 

 48 void MaxSum( long long int x )

 49 {

 50     long long int temp = 0;

 51 

 52     if ( m == k )

 53     {

 54         printf("%lld", num[0]);

 55         for ( int i = 1; i < m; i++ )

 56           printf(" / %lld", num[i]);

 57         putchar('\n');

 58         return;

 59     }

 60 

 61     if ( k == 1 )

 62     {

 63         printf("%lld", num[0]);

 64         for ( int i = 1; i < m; i++ )

 65           printf(" %lld", num[i]);

 66         putchar('\n');

 67         return;

 68     }

 69 

 70     int i = 0, j = 0;

 71     memset( w, false, sizeof(w) );

 72 

 73     for ( i = m - 1; i >= 0; )

 74     {

 75         temp += num[i];

 76         if ( temp <= x )

 77             i--;

 78         else

 79         {

 80             j++;

 81             w[i] = true;

 82             if ( k - j > i ) break;

 83             temp = 0;

 84         }

 85     }

 86 

 87     if ( j < k - 1 )

 88     {

 89         for ( int i = 0; i < m && j < k - 1; i++ )

 90             if ( !w[i] )

 91             {

 92                 w[i] = true;

 93                 j++;

 94             }

 95     }

 96 

 97     printf("%lld", num[0]);

 98     if ( w[0] )  printf(" /");

 99     for ( i = 1; i < m; i++ )

100     {

101         printf(" %lld", num[i]);

102         if ( w[i] && i != m - 1 )  printf(" /");

103     }

104 

105     putchar('\n');

106 

107     return;

108 }

109 

110 int main()

111 {

112     int T;

113     scanf( "%d", &T );

114     while ( T-- )

115     {

116         scanf("%d%d", &m, &k);

117         sum = 0;

118         for ( int i = 0; i < m; i++ )

119         {

120             scanf("%lld", &num[i]);

121             sum += num[i];

122         }

123 

124         MaxSum( Bsearch( 0, sum ) );

125     }

126     return 0;

127 }

你可能感兴趣的:(copy)