SRM 513 2 1000CutTheNumbers(状态压缩)

SRM 513 1000CutTheNumbers


Problem Statement

Manao has a board filled with digits represented as String[] board. The j-th character of the i-th element of board represents the digit written in cell in row i, column j of the board. The rows are numbered from top to bottom and the columns are numbered from left to right. 

Manao is going to cut it into several non-overlapping fragments. Each of the fragments will be a horizontal or vertical strip containing 1 or more elements. A strip of length N can be interpreted as an N-digit number in base 10 by concatenating the digits on the strip in order. The horizontal strips are read from left to right and the vertical strips are read from top to bottom. The picture below shows a possible cutting of a 4x4 board: 

The sum of the numbers on the fragments in this picture is 493 + 7160 + 23 + 58 + 9 + 45 + 91 = 7879. 

Manao wants to cut the board in such a way that the sum of the numbers on the resulting fragments is the maximum possible. Compute and return this sum.

Definition

  • ClassCutTheNumbers
  • MethodmaximumSum
  • Parametersvector<string>
  • Returnsint
  • Method signatureint maximumSum(vector<string> board)
(be sure your method is public)

Limits

  • Time limit (s)2.000
  • Memory limit (MB)64

Notes

  • The numbers on the cut strips are allowed to have leading zeros. See example #2 for details.

Constraints

  • board will contain between 1 and 4 elements, inclusive.
  • board[0] will be between 1 and 4 characters long, inclusive.
  • Each element of board will be of the same length as board[0].
  • Each character in board will be a decimal digit ('0'-'9').

Test cases

  1.  
    • board{"123",
       "312"}
     
    Returns435
     
    Manao can cut out both rows in whole, obtaining 123 + 312 = 435. He also could cut the columns one by one for a total of 66, or cut the first column and the residual rows one by one, obtaining 13 + 23 + 12 = 48, or even cut out single elements, but would not get a better sum.
  2.  
    • board{"99",
       "11"}
     
    Returns182
     
    It's better to cut out the whole columns.
  3.  
    • board{"001",
       "010",
       "111",
       "100"}
     
    Returns1131
     
    The numbers on the strips may have leading zeros. Cutting the columns in whole, Manao obtains 0011 + 0110 + 1010 = 1131.
  4.  
    • board{ "8" }
     
    Returns8

This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.

你可以认为0的话,就是向左连,1的话就是向下连。

然后状态压缩一下。枚举所有的状态即可。

  1 #include <cstdio>
  2 #include <cmath>
  3 #include <cstring>
  4 #include <ctime>
  5 #include <iostream>
  6 #include <algorithm>
  7 #include <set>
  8 #include <vector>
  9 #include <sstream>
 10 #include <typeinfo>
 11 #include <fstream>
 12 
 13 using namespace std;
 14 const int inf = 0x3f3f3f3f ;
 15 int n , m ;
 16 int maxn ;
 17 int path[5] ;
 18 vector<int> b[10] ;
 19 class CutTheNumbers {
 20     public:
 21     int maximumSum(vector<string> board) {
 22         n = board.size () ;
 23         m = board[0].size () ;
 24         for (int i = 0 ; i < n ; i ++) b[i].clear () ;
 25         for (int i = 0 ; i < n ; i ++) {
 26             for (int j = 0 ; j < m ; j ++) {
 27                 b[i].push_back( board[i][j] - '0' );
 28             }
 29         }
 30         maxn = - inf ;
 31         dfs (0) ; 
 32         return maxn ;
 33     }
 34 
 35     void dfs (int dep) {
 36         if (dep == n) {
 37             solve () ;
 38             return ;
 39         }
 40         for (int i = 0 ; i < (1 << m) ; i ++) {
 41            path[dep] = i ;
 42            dfs (dep + 1) ;
 43         }
 44     }
 45 
 46     void solve () {
 47         bool map[5][5] ;
 48         int ans = 0 ;
 49         memset (map , 0 , sizeof(map) ) ;
 50     
 51         for (int i = 0 ; i < n ; i ++) {
 52             int j = 0 ;
 53             int tmp = path[i] ;
 54             while (tmp) {
 55                 map[i][j ++] = tmp & 1 ;
 56                tmp>>= 1 ;
 57             }
 58             reverse (map[i] , map[i] + m) ;
 59         }
 60         
 61         bool mark[5][5] ;
 62         memset (mark , 0 , sizeof(mark) ) ;
 63 
 64         for (int i = 0 ; i < n ; i ++) {
 65             for (int j = 0 ; j < m ; j ++) {
 66                 if (!mark[i][j]) {
 67                     int tmp = 0 ;
 68                     if (!map[i][j]) {
 69                         for (int k = j ; k < m && !map[i][k] ; k ++) {
 70                             mark[i][k] = 1 ;
 71                             tmp = tmp * 10 + b[i][k] ;
 72                         }
 73                     }
 74                     else {
 75                         for (int k = i ; k < n && map[k][j] ; k ++) { 
 76                             mark[k][j] = 1 ;
 77                             tmp = tmp * 10 + b[k][j] ;
 78                         }
 79                     }
 80                     ans += tmp ;
 81                 }
 82             }
 83         }
 84         maxn = max (maxn , ans) ;
 85     }
 86 
 87                             
 88 };
 89 
 90 // CUT begin
 91 ifstream data("CutTheNumbers.sample");
 92 
 93 string next_line() {
 94     string s;
 95     getline(data, s);
 96     return s;
 97 }
 98 
 99 template <typename T> void from_stream(T &t) {
100     stringstream ss(next_line());
101     ss >> t;
102 }
103 
104 void from_stream(string &s) {
105     s = next_line();
106 }
107 
108 template <typename T> void from_stream(vector<T> &ts) {
109     int len;
110     from_stream(len);
111     ts.clear();
112     for (int i = 0; i < len; ++i) {
113         T t;
114         from_stream(t);
115         ts.push_back(t);
116     }
117 }
118 
119 template <typename T>
120 string to_string(T t) {
121     stringstream s;
122     s << t;
123     return s.str();
124 }
125 
126 string to_string(string t) {
127     return """ + t + """;
128 }
129 
130 bool do_test(vector<string> board, int __expected) {
131     time_t startClock = clock();
132     CutTheNumbers *instance = new CutTheNumbers();
133     int __result = instance->maximumSum(board);
134     double elapsed = (double)(clock() - startClock) / CLOCKS_PER_SEC;
135     delete instance;
136 
137     if (__result == __expected) {
138         cout << "PASSED!" << " (" << elapsed << " seconds)" << endl;
139         return true;
140     }
141     else {
142         cout << "FAILED!" << " (" << elapsed << " seconds)" << endl;
143         cout << "           Expected: " << to_string(__expected) << endl;
144         cout << "           Received: " << to_string(__result) << endl;
145         return false;
146     }
147 }
148 
149 int run_test(bool mainProcess, const set<int> &case_set, const string command) {
150     int cases = 0, passed = 0;
151     while (true) {
152         if (next_line().find("--") != 0)
153             break;
154         vector<string> board;
155         from_stream(board);
156         next_line();
157         int __answer;
158         from_stream(__answer);
159 
160         cases++;
161         if (case_set.size() > 0 && case_set.find(cases - 1) == case_set.end())
162             continue;
163 
164         cout << "  Testcase #" << cases - 1 << " ... ";
165         if ( do_test(board, __answer)) {
166             passed++;
167         }
168     }
169     if (mainProcess) {
170         cout << endl << "Passed : " << passed << "/" << cases << " cases" << endl;
171         int T = time(NULL) - 1436409000;
172         double PT = T / 60.0, TT = 75.0;
173         cout << "Time   : " << T / 60 << " minutes " << T % 60 << " secs" << endl;
174         cout << "Score  : " << 1000 * (0.3 + (0.7 * TT * TT) / (10.0 * PT * PT + TT * TT)) << " points" << endl;
175     }
176     return 0;
177 }
178 
179 int main(int argc, char *argv[]) {
180     cout.setf(ios::fixed, ios::floatfield);
181     cout.precision(2);
182     set<int> cases;
183     bool mainProcess = true;
184     for (int i = 1; i < argc; ++i) {
185         if ( string(argv[i]) == "-") {
186             mainProcess = false;
187         } else {
188             cases.insert(atoi(argv[i]));
189         }
190     }
191     if (mainProcess) {
192         cout << "CutTheNumbers (1000 Points)" << endl << endl;
193     }
194     return run_test(mainProcess, cases, argv[0]);
195 }
196 // CUT end
View Code
原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4637710.html