SRM 386 500pt: PolygonCover
問題概要
凸多角形(頂点数N<=15)が与えられる。この頂点を複数個選んでできる多角形を集めて頂点を被覆したい。面積の和を最小化する問題。ただし面積が重複している部分は複数回カウントする。
考えたこと
practiceで通ったコード
計算量O(2^N * N^3)。
#include <vector> #include <algorithm> using namespace std; const int MAX_N = 15; const int INF = 1<<29; int dp[1<<MAX_N]; struct PolygonCover { double getArea(vector <int> x, vector <int> y) { const int N = x.size(); //初期化 fill(dp, dp+(1<<N), INF); //基底 dp[0] = 0; //ビットDP for(int bit=0; bit<(1<<N); bit++){ //新たに三角形を作ってかぶせる for(int i=0; i<N; i++){ for(int j=i+1; j<N; j++){ for(int k=j+1; k<N; k++){ int next_bit = bit | (1<<i) | (1<<j) | (1<<k); int area = dp[bit] + getTriangleArea(x[i], y[i], x[j], y[j], x[k], y[k]); dp[next_bit] = min(dp[next_bit], area); } } } } return (double)dp[(1<<N)-1]/2.0; } //三角形の面積の2倍の値を返す inline int getTriangleArea(int x1, int y1, int x2, int y2, int x3, int y3){ return abs((y2-y3)*(x1-x3) - (x2-x3)*(y1-y3)); } };