日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDU 5473 There was a kingdom 凸包 DP

發布時間:2025/4/9 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU 5473 There was a kingdom 凸包 DP 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題意:

給出平面上n個點的坐標,選k個點,使得這k個點圍起來的面積最大.

分析:

參考了 叉姐的分析 和 不慌不忙菊苣的代碼
思路我都懂,但是DP的部分還是不太會寫.
我體會了一下其中含義,也許這樣可能會好理解一點:
因為求出來的凸包的點數是固定的,所能選的點數也是固定的,那么不選的點的數量也是固定的.
可以反過來考慮:少選一個點,就要損失凸包上的一塊面積.
假設\(d(i,j)\)表示考慮了前\(i\)個點,選了\(j\)個點,所損失的最少面積.
\(i\)個點的前一個點是\(i'\),損失的面積為\(S_{cut}\),那么\(d(i,j)=min(d(i,j),d(i',j-1)+S_{cut})\)

最后答案就是凸包總面積減去最后損失的最小面積.

損失的面積是一小塊一小塊三角形累加起來的.
上個圖片僅供參考:

#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std;typedef long long LL;const int maxn = 100 + 10;struct Point {LL x, y;Point(LL x = 0, LL y = 0) : x(x), y(y) {}void read() { scanf("%lld%lld", &x, &y); } };Point operator - (const Point& A, const Point& B) {return Point(A.x - B.x, A.y - B.y); }bool operator < (const Point& A, const Point& B) {return A.x < B.x || (A.x == B.x && A.y < B.y); }LL Cross(const Point& A, const Point& B) {return A.x * B.y - A.y * B.x; }vector<Point> p, con;vector<Point> ConvexHull() {sort(p.begin(), p.end());int n = p.size();vector<Point> ch(n);int m = 0;for(int i = 0; i < n; i++) {while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) < 0) m--;ch[m++] = p[i];}int k = m;for(int i = n - 2; i >= 0; i--) {while(m > k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) < 0) m--;ch[m++] = p[i];}if(n > 1) m--;ch.resize(m);return ch; }int n, k;LL d[maxn][maxn]; bool vis[maxn];int main() {//freopen("in.txt", "r", stdin);int _; scanf("%d", &_);for(int __ = 1; __ <= _; __++) {scanf("%d%d", &n, &k);p.resize(n);for(int i = 0; i < n; i++) p[i].read();con = ConvexHull();int sz = con.size();if(sz <= 2 || k <= 2) { printf("0\n"); continue; }LL totarea = 0;for(int i = 2; i < sz; i++) totarea += Cross(con[i-1]-con[0], con[i] - con[0]);if(k >= sz) {printf("%lld\n", totarea);continue;}LL ans = 0x3f3f3f3f3f3f3f3f;memset(vis, false, sizeof(vis));int times = min(10 * n / k, sz);while(times--) {int s = rand() % sz;while(vis[s]) s = rand() % sz;vis[s] = true;memset(d, 0x3f, sizeof(d));d[0][0] = 0;for(int i = 1; i <= sz; i++) {int p0 = (s + i) % sz;LL cut = 0;for(int j = i - 1; j >= 0; j--) {int p2 = (s + j) % sz;int p1 = (p2 + i) % sz;cut += Cross(con[p1] - con[p0], con[p2] - con[p0]);for(int l = k; l > 0; l--)d[i][l] = min(d[i][l], d[j][l-1] + cut);}}ans = min(ans, d[sz][k]);}printf("Case #%d: %lld\n", __, totarea - ans);}return 0; }

轉載于:https://www.cnblogs.com/AOQNRMGYXLMV/p/4864442.html

總結

以上是生活随笔為你收集整理的HDU 5473 There was a kingdom 凸包 DP的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。