题目的分析在http://apps.topcoder.com/wiki/display/tc/TCO+2013+Round+1B
当时比赛的时候用贪心做的,也就是每次都找X数目最多的行或者列,结果挂了。。。没经过证明的贪心算法的确是不靠谱啊。。。
注意到行的最大值仅仅是15,因此可以进行枚举,具体可以用位掩膜来实现,更重要的一点是:
一旦行的消除确定下来,那么要除去那些列是唯一确定的!这是当时困扰我的最大地方,怎么这么点破事都没想清楚。。。
最后一个问题:如果确定那些行需要删除,最小的列删除数目是多少?可以用贪心法解决。
代码如下,已经通过了system test:
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
class EllysFigurines {
public:
int getMoves(vector <string>, int, int);
//using greedy method to get minimal moves
int solve(int mask, int L){
int index = 0;
int res = 0;
while(index < 15){
if((mask&(1<<index)) != 0){
res++;
index += L;
}
else index++;
}
return res;
}
};
int EllysFigurines::getMoves(vector <string> board, int R, int C) {
int row = board.size();
int col = board[0].size();
int res = 20;
//use bit mask to search minimal result
for(int i=0; i<(1<<row); i++){
int mask2 = 0;
for(int j=0; j<row; j++){
if((i&(1<<j)) == 0){
for(int k=0; k<col; k++){
if(board[j][k] == 'X')
mask2 |= (1<<k);
}
}//end if
}//end for loop
res = min(res, solve(i, R)+solve(mask2, C));
}
return res;
}
//<%:testing-code%>
//Powered by [KawigiEdit] 2.0!