自己的網路流水平還是遠遠不夠
一開始以為是費用流搞了半天,發現無法處理只有第一次有效的情況
於是看題解才知道就是個最大權閉合子圖
由於每種東西都只有第一次有效
那麼我們可以考慮把區間作為點建圖
考慮最大權閉合子圖的模型
選擇區間\((i,j)\)的貢獻就一定要選擇區間\((i+1,j),(i,j-1)\)的貢獻
所以我們就把區間\((i,j)\)向\((i+1,j),(i,j-1)\)連邊
流量為inf
然後如果選擇\(i~j\)這段連續區間的壽司的額外收益\(d[i][j]\)是正的就由源點連流量為收益的邊
否則就向匯點連邊
只有\(i==j\)的區間才向每個壽司連邊
然後每種壽司選c個的花費是\(m*id^2+c*id\)
也就是說每個種類的壽司只會被計算一次\(m*id^2\)
但是會被計算\(c\)次\(id\)
所以就對於每種壽司建乙個點向終點連\(m*id^2\)的邊表示選擇這種壽司就一定會先花費這些錢
然後再對於每個壽司建乙個點,向表示ta的種類的點連\(inf\)的邊表示選擇這個壽司就已經選擇了這個種類的壽司,然後再向終點連流量為\(id\)的邊表示選擇這個壽司的費用
#include#include#include#include#includeconst int m = 105 ;
const int n = 13005 ;
const int inf = 1e9 ;
using namespace std ;
inline int read()
while(c>='0'&&c<='9')
return x*w ;
}int n , m , num = 1 , hea[n] ;
int bel[m] , d[m][m] ;
int s , t , ans , cnt , idt[m][m] , dep[n] ;
struct e edge[n * 10] ;
inline void add_edge(int from , int to , int dis)
inline void insert(int from , int to , int dis)
inline bool bfs()
} }return dep[t] ;
}int dfs(int u , int dis)
} }if(!sum) dep[u] = -1 ;
return sum ;
}inline int dinic()
int main()
cnt = n + 1000 ;
for(int i = 1 ; i <= n ; i ++)
for(int j = i ; j <= n ; j ++)
idt[i][j] = ++ cnt ;
for(int i = 1 ; i <= n ; i ++)
else insert(idt[i][i] , t , -d[i][i]) ;
} for(int i = 1 ; i <= n ; i ++)
for(int j = i + 1 ; j <= n ; j ++)
else insert(idt[i][j] , t , -d[i][j]) ;
} ans -= dinic() ;
printf("%d\n",ans) ;
return 0 ;
}
六省聯考 2017 壽司餐廳
戳我 簡要題目 乙個序列,可以若干次取其中一段區間,區間及其子集的價值都會被統計進去且每個區間的價值只能被統計一次。如果你拿 c 種 x 數,你需要花費 m x 2 c x 的代價。求最大價值。這道題看起來並沒有思路,看了看題解後發現這是最大權閉合子圖。what?這是神馬?不會,於是去學了一下。然後...
六省聯考 壽司餐廳
太長了,不描述!看題面看了10min才反應過來這是個最大權值閉合子圖的問題 應用網路流最小割的模型來解決本問題 首先,每個壽司編號即為器材,代價為 w i w i m 那麼我們由每個壽司編號向匯點鏈結一條容量為w i w i m 每個壽司一定需要乙個壽司編號,代價為 w i 那麼我們由壽司向壽司編號...
P3749 六省聯考2017 壽司餐廳
首先因為每個值只會被算一次且值的個數為 n 2 級別的,因此我們可以對每個 d 開乙個點,之後就可以用最大權閉合子圖做。考慮題目的限制 1.選擇乙個區間 l,r 會將 sum limits sum limits rd 選上 我們顯然不能全部連上,這是 n 4 級別的,我們可以只從 d 向 d 和 d...