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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

[ZJOI2015]幻想乡 Wi-Fi 搭建计划(dp + 结论)

發布時間:2023/12/3 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [ZJOI2015]幻想乡 Wi-Fi 搭建计划(dp + 结论) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

problem

luogu-P3344

solution

這個題面,這個數據范圍,完完全全就是網絡流宗教。。然而我發現建不出來。

很多一眼網絡流最后卻不是網絡流而往往是 dpdpdp 的題目都有一個特性:一個點可以流出多條流量,流入流量卻只能為 111。

我曾嘗試過對點加兩條邊,一條流量為 111 帶花費,另一條流量無窮不帶花費,然后強制先流特殊邊,這就必須要用費用流來做到。

但題目所求往往相反,也就是我強制先流要用負花費,求出的是最大費用,而題目卻要最小費用。


首先我們把所有不能被任何一個網絡架點覆蓋的景點刪去,就解決了第一小問。

問題轉化成了將所有點全覆蓋的最小花費。

此題需要尋找一個結論:景點按 xxx 排序后,每個網絡架點覆蓋的點一定是景點的一段連續區間。

由 所有網絡架的圓心都在矩形外 以及 所有網絡架的半徑均相同 這兩個性質確保該結論的正確性。

注意這個結論是 所有圓心均在矩形上方 / 所有圓心均在矩形下方 分類后才成立。

于是我們就設 f(i,j,k):f(i,j,k):f(i,j,k): 考慮前 iii 個景點,最后一次使用圓心在矩陣上方的網絡架為 jjj,最后一次使用圓心在矩陣下方的網絡架為 kkk。

iii 景點能被圓心在矩陣上方的第 jjj 個網絡架覆蓋,則再枚舉一下矩陣上方的網絡架上一次用的是哪個:

f(i,j,k)=min?{f(i?1,o,k)}+c(j)f(i,j,k)=\min\{f(i-1,o,k)\}+c(j)f(i,j,k)=min{f(i?1,o,k)}+c(j)。

圓心在矩陣下方的轉移同理。

時間復雜度就是非常樸素的 O(n4)O(n^4)O(n4)。

注意:我們的 fff 狀態設計不再是常見到,使用前 j/kj/kj/k 個圓心在矩陣上 / 下方的網絡架,而是直接最近一次使用的編號。

所以實際上這個網絡架的使用編號是反復變化跳躍的。

看似并不是一個圓會覆蓋一段連續點的方案。

但實際上這些不合法的方案一定不會成為最優解,因為多次計算了網絡架點的搭建花費。

而一個圓覆蓋一段連續點的最優方案也統計進了,所以最后答案是不會受到影響的。

code

#include <bits/stdc++.h> using namespace std; #define int long long #define maxn 105 int n, m, R, cnt, cntd, cntu; int f[maxn][maxn][maxn]; struct NB { int x, y; }s[maxn], g[maxn]; struct DK { int x, y, c; }p[maxn], d[maxn], u[maxn];bool check( DK o, NB w ) { return (o.x - w.x) * (o.x - w.x) + (o.y - w.y) * (o.y - w.y) <= R * R; }signed main() {scanf( "%lld %lld %lld", &n, &m, &R );for( int i = 1;i <= n;i ++ ) scanf( "%lld %lld", &s[i].x, &s[i].y );for( int i = 1;i <= m;i ++ ) scanf( "%lld %lld %lld", &p[i].x, &p[i].y, &p[i].c );for( int i = 1;i <= n;i ++ ) {for( int j = 1;j <= m;j ++ )if( check( p[j], s[i] ) ) {g[++ cnt] = s[i];break;}}sort( g + 1, g + cnt + 1, []( NB a, NB b ) { return a.x < b.x; } );for( int i = 1;i <= m;i ++ )if( p[i].y < 0 ) d[++ cntd] = p[i];else u[++ cntu] = p[i];memset( f, 0x3f, sizeof( f ) );f[0][0][0] = 0;for( int i = 1;i <= cnt;i ++ )for( int j = 0;j <= cntu;j ++ )for( int k = 0;k <= cntd;k ++ ) {if( j and check( u[j], g[i] ) ) {f[i][j][k] = f[i - 1][j][k];for( int o = 0;o <= cntu;o ++ )f[i][j][k] = min( f[i][j][k], f[i - 1][o][k] + u[j].c );}if( k and check( d[k], g[i] ) ) {f[i][j][k] = f[i - 1][j][k];for( int o = 0;o <= cntd;o ++ )f[i][j][k] = min( f[i][j][k], f[i - 1][j][o] + d[k].c );}}int ans = 1e18;for( int i = 0;i <= cntu;i ++ )for( int j = 0;j <= cntd;j ++ )ans = min( ans, f[cnt][i][j] );printf( "%lld\n%lld\n", cnt, ans );return 0; }

總結

以上是生活随笔為你收集整理的[ZJOI2015]幻想乡 Wi-Fi 搭建计划(dp + 结论)的全部內容,希望文章能夠幫你解決所遇到的問題。

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