首页 > 其他 > 详细

Pokemon Go Go (状压dp)

时间:2020-10-01 10:24:48      阅读:38      评论:0      收藏:0      [点我收藏+]
//捕捉宝可梦
//考虑状压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;
}

Pokemon Go Go (状压dp)

原文:https://www.cnblogs.com/wanshe-li/p/13757296.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!