最大值最小化问题,二分+贪心,参考刘汝佳白皮书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 }