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 }
posted @ 2012-07-29 13:44  冰鸮  阅读(179)  评论(0编辑  收藏  举报