Pokemon Go Go (状压dp)
作者:互联网
//捕捉宝可梦
//考虑状压dp,一维是宝可梦的捕捉状态,二维保存当前捕捉的宝可梦编号
const int inf = 0x3f3f3f3f;
int n, cnt;
int dp[1 << 20][22];//dp[sta][point]
unordered_map<string, int> mp;
struct point {
int x, y;
int type;
};
point a[25];
string s;
int get_cal(point i, point j) {
return abs(i.x - j.x) + abs(i.y - j.y);
}
int main() {
ios::sync_with_stdio(0);
while (cin >> n) {
for (int i = 0; i < n; ++i) {
cin >> a[i].x >> a[i].y;
cin >> s;
if (!mp.count(s)) mp[s] = cnt++;
a[i].type = mp[s];
}
memset(dp, inf, sizeof dp);
for (int i = 0; i < n; ++i) {//初始化:原点到每种宝可梦的最短距离
dp[(1 << a[i].type)][i] = min(dp[(1 << a[i].type)][i], get_cal(a[n + 3], a[i]));//a[n+3]可看作原点
}
int limit = (1 << cnt);
for (int i = 0; i < limit; ++i) {//枚举状态
if ((i == (i & -i))) continue;//已经初始化,跳过
for (int j = 0; j < n; ++j) {//当前选择的点
if (!(i & (1 << a[j].type))) continue;
int last = i - (1 << a[j].type);//前一次的状态
for (int k = 0; k < n; ++k) {//前一次选择的点
if (last & (1 << a[k].type)) dp[i][j] = min(dp[i][j], dp[last][k] + get_cal(a[k], a[j]));
}
}
}
int ans = inf;
for (int i = 0; i < n; ++i)
ans = min(ans, dp[limit - 1][i] + get_cal(a[n + 3], a[i]));//a[n+3]未初始化,为(0,0)
cout << ans << endl;
}
return 0;
}
标签:point,int,状压,宝可梦,++,mp,Go,Pokemon,dp 来源: https://www.cnblogs.com/wanshe-li/p/13757296.html