ZOJ3537 解题报告及总结
2016-02-25 20:01
295 查看
题目意思就是 给你一个多边形,先判断是否是凸包,然后再划分成一个一个三角形,求最小代价,两点之间画一条线的最小代价为 abs(xi + xj) * abs(yi + yj) % p 才做的时候,想法是枚举划分的线,根据分治的思想,大的多边形拆成两个小多边形,然后记忆化,复杂度超高难写不说(因为要记录i节点的nxt节点编号,不停地变来变去),还不知道wa在哪。。 后来想了下,既然最后一定是一个一个的三角形,那么多边形的一条边肯定是三角形的边,那么挨着的两个点,一定在一个三角形内,那么只需要枚举第三个定点,复杂度降低一维,而且很好写
// // Created by Running Photon on 2016-02-25 // Copyright (c) 2015 Running Photon. All rights reserved. // #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <sstream> #include <set> #include <vector> #include <stack> #define ALL(x) x.begin(), x.end() #define INS(x) inserter(x, x,begin()) #define ll long long #define CLR(x) memset(x, 0, sizeof x) using namespace std; const ll inf = 0x3f3f3f3f3f3f3f3f; const int MOD = 1e9 + 7; const int maxn = 1e6 + 10; const double eps = 1e-9; struct Point { ll x, y; Point(ll _x = 0, ll _y = 0) : x(_x), y(_y) {} void read() { scanf("%lld%lld", &x, &y); } bool operator< (const Point rhs) const { if(x == rhs.x) return y < rhs.y; return x < rhs.x; } void print() { printf("%lld %lld\n", x, y); } Point operator+ (Point rhs) { return Point(x + rhs.x, y + rhs.y); } Point operator- (Point rhs) { return Point(x - rhs.x, y - rhs.y); } Point operator* (ll rhs) { return Point(x * rhs, y * rhs); } Point operator/ (ll rhs) { return Point(x / rhs, y / rhs); } ll operator* (Point rhs) { return x * rhs.x + y * rhs.y; } ll operator^ (Point rhs) { return x * rhs.y - y * rhs.x; } }; vector <Point> Gh(vector <Point>& a) { vector <Point> res; int m = 0; sort(ALL(a)); if(a.size() <= 2) { for(int i = 0; i < a.size(); i++) { res.push_back(a[i]); } res.push_back(a[0]); } for(int i = 0; i < a.size(); i++) { while(m > 1 && ((res[m-1] - res[m-2]) ^ (a[i] - res[m-2])) <= 0) { m--; res.pop_back(); } m++; res.push_back(a[i]); } int k = m; for(int i = a.size() - 2; i >= 0; i--) { while(m > k && ((res[m-1] - res[m-2]) ^ (a[i] - res[m-2])) <= 0) { m--; res.pop_back(); } m++; res.push_back(a[i]); } res.pop_back(); return res; } vector <Point> gh; int n; ll p; ll calc(Point l, Point r) { return abs(l.x + r.x) * abs(l.y + r.y) % p; } ll cost[305][305]; ll dp[305][305]; int nxt[305]; ll dfs(int l, int r) { if(r - l <= 2) return 0; if(dp[l][r] != -1) return dp[l][r]; ll& ret = dp[l][r]; ret = inf; for(int i = l + 1; i < r; i++) { ret = min(ret, dfs(l, i) + dfs(i, r) + cost[i][l] + cost[i][r]); } return ret; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif // ios_base::sync_with_stdio(0); while(scanf("%d%lld", &n, &p) != EOF) { memset(dp, -1, sizeof dp); CLR(cost); gh.clear(); vector <Point> g; for(int i = 0; i < n; i++) { ll x, y; scanf("%lld%lld", &x, &y); g.push_back(Point(x, y)); } vector <Point> gh = Gh(g); for(int i = 0; i < gh.size(); i++) { for(int j = i + 2; j < gh.size(); j++) { cost[j][i] = cost[i][j] = calc(gh[i], gh[j]); } } // printf("%d\n", gh.size()); // for(int i = 0; i < gh.size(); i++) { // gh[i].print(); // } if(gh.size() != g.size()) { puts("I can't cut."); continue; } printf("%lld\n", dfs(0, gh.size() - 1)); } return 0; }
相关文章推荐
- H2的存储子系统——MvStore
- Eclipse常用设置
- Walking on a Grid uva10913
- python简单的绘制折现图
- 观察者模式的初始学习--自己实现
- CocoaPods和git
- main()函数
- 访问单个节点的删除
- 进程环境 知识点汇总《APUE》 chapter-7
- install php
- JNIEnv常用方法
- VS2010添加类失败问题,弹出错误框,提示 CodeModel操作失败,无法访问标记数据库
- 《leetCode》:Construct Binary Tree from Inorder and Postorder Traversal
- [Leetcode] 212. Word Search @python
- iptables实现网络防火墙及地址转换
- 10 循环和自增-DirectX游戏开发初级教程
- H5手游也能月流水千万!您还在靠IP拉客?
- 毕业前夕一
- 最小的k个数
- iptables实现网络防火墙及地址转换