zoukankan      html  css  js  c++  java
  • HDU 4739 Zhuge Liang's Mines (状态压缩+背包DP)

    题意

    给定平面直角坐标系内的N(N <= 20)个点,每四个点构成一个正方形可以消去,问最多可以消去几个点。

    思路

    比赛的时候暴力dfs+O(n^4)枚举写过了……无意间看到有题解用状压DP(这才是正解吧T_T),然后自己才恍然大悟- -…… 点不多嘛,用一个20位的整数表示各个点。先O(n^4)枚举出所有正方形情况,然后把这20位当背包,每种情况的二进制位当物品,做01背包就可以了. 似乎遇到N = 10+、20+的都应该想想状态压缩>.<……

    代码

      [cpp] #include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <string> #include <cstring> #include <vector> #include <set> #include <stack> #include <queue> #define MID(x,y) ((x+y)/2) #define MEM(a,b) memset(a,b,sizeof(a)) #define REP(i, begin, end) for (int i = begin; i <= end; i ++) using namespace std; vector <int> v; struct Point{ int x, y; }p[25]; bool cmp(Point p1, Point p2){ if (p1.x == p2.x) return p1.y < p2.y; else return p1.x < p2.x; } int dp[1050000]; int main(){ int n; while(scanf("%d", &n)){ if (n < 0) break; for (int i = 0; i < n; i ++){ scanf("%d %d", &p[i].x, &p[i].y); } sort(p, p+n, cmp); v.clear(); for (int i = 0; i < n; i ++) for (int j = i + 1; j < n; j ++) if (p[i].x == p[j].x){ int dy = abs(p[i].y - p[j].y); for (int k = j + 1; k < n; k ++) if (p[k].y == p[i].y && p[k].x == p[i].x + dy) for (int l = k + 1; l < n; l ++){ if (p[l].y == p[j].y && p[l].x == p[i].x + dy) v.push_back((1<<i)|(1<<j)|(1<<k)|(1<<l)); } } MEM(dp, 0); int res = 0; for (int i = 0; i < (int)v.size(); i ++){ for (int mk = (1<<n)-1; mk >= 0; mk --){ if ((mk & v[i]) == v[i]) dp[mk] = max(dp[mk], dp[mk-v[i]]+4); res = max(res, dp[mk]); } } printf("%d ", res); } return 0; } [/cpp]
  • 相关阅读:
    MKMapVIew学习系列2 在地图上绘制出你运行的轨迹
    WPF SDK研究 Intro(6) WordGame1
    WPF SDK研究 Intro(3) QuickStart3
    WPF SDK研究 Layout(1) Grid
    WPF SDK研究 目录 前言
    WPF SDK研究 Intro(7) WordGame2
    WPF SDK研究 Layout(2) GridComplex
    对vs2005创建的WPF模板分析
    WPF SDK研究 Intro(4) QuickStart4
    《Programming WPF》翻译 第6章 资源
  • 原文地址:https://www.cnblogs.com/AbandonZHANG/p/4114125.html
Copyright © 2011-2022 走看看