E - Dividing Chocolate
E - Dividing Chocolate
https://atcoder.jp/contests/abc159/tasks/abc159_e
思路
https://www.cnblogs.com/ycx-akioi/p/AtCoder-abc159.html
行数少,列数多,
对行应用组合方法,列举每种组合情况,
对每种组合情况, 对列进行贪心获取最长串,使得串和不大于k
Code
https://atcoder.jp/contests/abc159/submissions/38903482
int h, w, k; vector<vector<int>> s(16, vector<int>(1006, 0)); //int s[16][1006]; // prefix sum vector<vector<int>> ps(16, vector<int>(1006, 0)); //int ps[16][1006]; vector<int> hcuts; vector<int> hlines; vector<int> vlines; int main() { cin >> h >> w >> k; // if(h>15 || w>105){ // return 0; // } REP(i, h){ int hi = i+1; REP(j, w){ int wj = j+1; char one; cin >> one; s[hi][wj] = (one=='1'?1:0); // cout << s[hi][wj]; ps[hi][wj] = s[hi][wj] + ps[hi-1][wj] + ps[hi][wj-1] - ps[hi-1][wj-1]; } // cout << endl; } if (ps[h][w] <= k){ cout << 0 << endl; return 0; } int mincuts = (h-1) * (w-1); // horizontally split int rc = pow(2, h-1)-1; for(int i=0; i<=rc; i++){ // cout << "----------- combination i = " << i << " ----------" << endl; int num=i; // figure out cuts of horizons hcuts.clear(); for(int j=1;num>0; j++){ // cout << "j = " << j << endl; // cout << "i&j == j ===> " << ((i&j) == j) << endl; if(num%2==1){ hcuts.push_back(j); } num/=2; } // // cout << "------ hcuts: combination individual cases --------" << endl; // REP(j, hcuts.size()){ // cout << hcuts[j] << " "; // } // cout << endl; /* hlines: 0 1 3 ------ 0 1 2 3 ------ 1 4 5 6 7 8 9 ----- 3 */ hlines.clear(); hlines.push_back(0); REP(j, hcuts.size()){ hlines.push_back(hcuts[j]); } hlines.push_back(h); // // cout << "--------- hlines --------" << endl; // REP(j, hlines.size()){ // cout << hlines[j] << " "; // } // cout << endl; // vertically split /* vlines: 0 1 3 |1|2 3| |4|5 6| |7|8 9| 0 1 3 */ vlines.clear(); vlines.push_back(0); bool hcuts_abort = false; while(true){ int vline_prev = vlines[vlines.size()-1]; int vline_now = vline_prev+1; // cout << "--> vline_prev=" << vline_prev << endl; // cout << "--> vline_now=" << vline_now << endl; while(vline_now<=w){ // cout << "try vline_now, it value=" << vline_now << endl; int hlines_len = hlines.size(); /* --------- 0 |1|2 3| --------- 1 |4|5 6| |7|8 9| --------- 3 0 1 3 */ bool greatk = false; for(int i=1; i<hlines_len; i++){ int hline_prev = hlines[i-1]; int hline_now = hlines[i]; // cout << "hline_prev=" << hline_prev << endl; // cout << "hline_now=" << hline_now << endl; int rectsum = ps[hline_now][vline_now] - ps[hline_now][vline_prev] - ps[hline_prev][vline_now] + ps[hline_prev][vline_prev]; // cout << "rectsum = " << rectsum << endl; if (rectsum>k){ // vertially first try is failed by move one step from vline_prev // it means some vertial segment has greater white blocks than k in one first try if(vline_now == vline_prev+1){ hcuts_abort = true; } else { vlines.push_back(vline_now-1); } greatk = true; break; } } if(greatk){ break; } vline_now++; } // for last vertical segment, no need to cut if(vline_now > w){ break; } if(hcuts_abort){ break; } } vlines.push_back(w); if(hcuts_abort){ // cout << "----------- combination i = " << i << " aborted ----------" << endl; continue; } // // cout << "----------- combination i = " << i << " met, its solution ----------" << endl; // // cout << "--------- hlines --------" << endl; // REP(j, hlines.size()){ // cout << hlines[j] << " "; // } // cout << endl; // // cout << "--------- vlines --------" << endl; // REP(j, vlines.size()){ // cout << vlines[j] << " "; // } // cout << endl; int cuts_num = hlines.size() - 2 + vlines.size() - 2; // cout << "----- current combination cuts ------"; // cout << cuts_num << endl; mincuts = min(mincuts, cuts_num); } cout << mincuts << endl; return 0; }
出处:http://www.cnblogs.com/lightsong/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。