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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[HNOI2013]切糕

發(fā)布時(shí)間:2025/7/25 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [HNOI2013]切糕 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目描述

經(jīng)過千辛萬苦小 A 得到了一塊切糕,切糕的形狀是長(zhǎng)方體,小 A 打算攔腰將切糕切成兩半分給小 B。出于美觀考慮,小 A 希望切面能盡量光滑且和諧。于是她找到你,希望你能幫她找出最好的切割方案。

出于簡(jiǎn)便考慮,我們將切糕視作一個(gè)長(zhǎng) P、寬 Q、高 R 的長(zhǎng)方體點(diǎn)陣。我們將位于第 z層中第 x 行、第 y 列上(1≤x≤P, 1≤y≤Q, 1≤z≤R)的點(diǎn)稱為(x,y,z),它有一個(gè)非負(fù)的不和諧值 v(x,y,z)。一個(gè)合法的切面滿足以下兩個(gè)條件:

與每個(gè)縱軸(一共有 P*Q 個(gè)縱軸)有且僅有一個(gè)交點(diǎn)。即切面是一個(gè)函數(shù) f(x,y),對(duì)于所有 1≤x≤P, 1≤y≤Q,我們需指定一個(gè)切割點(diǎn) f(x,y),且 1≤f(x,y)≤R。

切面需要滿足一定的光滑性要求,即相鄰縱軸上的切割點(diǎn)不能相距太遠(yuǎn)。對(duì)于所有的 1≤x,x’≤P 和 1≤y,y’≤Q,若|x-x’|+|y-y’|=1,則|f(x,y)-f(x’,y’)| ≤D,其中 D 是給定的一個(gè)非負(fù)整數(shù)。 可能有許多切面f 滿足上面的條件,小A 希望找出總的切割點(diǎn)上的不和諧值最小的那個(gè)。

輸入輸出格式

輸入格式:

第一行是三個(gè)正整數(shù)P,Q,R,表示切糕的長(zhǎng)P、 寬Q、高R。第二行有一個(gè)非負(fù)整數(shù)D,表示光滑性要求。接下來是R個(gè)P行Q列的矩陣,第z個(gè) 矩陣的第x行第y列是v(x,y,z) (1<=x<=P, 1<=y<=Q, 1<=z<=R)。 100%的數(shù)據(jù)滿足P,Q,R<=40,0<=D<=R,且給出的所有的不和諧值不超過1000。

輸出格式:

僅包含一個(gè)整數(shù),表示在合法基礎(chǔ)上最小的總不和諧值。

輸入輸出樣例

輸入樣例#1:

2 2 2
1
6 1
6 1
2 6
2 6

輸出樣例#1:

6


題解

題目要求就是在一個(gè)\(n\times m\)的矩陣中填數(shù)
每個(gè)位置都是一個(gè)數(shù)軸,數(shù)軸上每一格都代表了一個(gè)數(shù),相鄰兩點(diǎn)間所選擇的數(shù)軸上的位置的距離不超過\(D\)
,問將矩陣填成\(n\times m\)的最小花費(fèi)
可以發(fā)現(xiàn)每個(gè)點(diǎn)的貢獻(xiàn)最多只能被計(jì)算一次
那么可以用最小割來解決
\(v_{i,j,k}\)表示第\(i\)行,第\(j\)列,數(shù)軸上選擇第\(k\)個(gè)點(diǎn)的值
我們可以把每個(gè)位置上的數(shù)軸的相鄰點(diǎn)\(v_{i,j,k-1}\to v_{i,j,k}\)之間連邊,流量就是\(v_{i,j,k}\)
這樣如果選擇了數(shù)軸上的第\(k\)個(gè)點(diǎn)就要割掉這條邊并花費(fèi)\(v_{i,j,k}\)
然后我們還需要考慮一個(gè)限制就是相鄰的點(diǎn)在數(shù)軸上選擇的距離不超過\(D\)
那么我們對(duì)于點(diǎn)\((i,j)\),只需滿足\(f(i,j)-f(x,y)\le d\)即可
因?yàn)槿绻?span id="ozvdkddzhkzd" class="math inline">\(f(i,j) - f(x,y) < -d\)
那么在點(diǎn)\((x,y)\)的限制中就成了\(f(x,y)-f(i,j) > d\)
那么這顯然不滿足條件
所以只連\((i,j,k) \to (i,j,k-d)\)的邊,流量為\(INF\),表示這條限制不會(huì)被割掉
有一位\(dalao\)的圖畫的肥腸形象
盜用一下以便理解==

代碼

/* 對(duì)于光滑的限制: 只需要考慮f(i,j) - f(x,y) <= d 即可 因?yàn)槿绻嬖?f(i,j) - f(x,y) < -d 那么換做f(x,y)的限制就成了f(x,y) - f(i.j) > d 也自然就不符合條件了*/ #include<queue> #include<cstdio> #include<cstring> #include<algorithm> const int N = 45 ; const int M = 100005 ; const int INF = 1e9 ; const int dx[] = {-1 , 0 , 1 , 0} ; const int dy[] = {0 , -1 , 0 , 1} ; using namespace std ; inline int read() {char c = getchar() ; int x = 0 , w = 1 ;while(c>'9'||c<'0') { if(c=='-') w = -1 ; c = getchar() ; }while(c>='0'&&c<='9') { x = x*10+c-'0' ; c = getchar() ; }return x*w ; }int n , m , h , d , S , T , cnt , num = 1 ; int id[N][N][N] , val[N][N][N] , hea[M] , dep[M] ;struct E { int nxt , to , dis ; } edge[M * 10] ; inline void Insert_edge(int from , int to , int dis) {edge[++num].nxt = hea[from] ; edge[num].to = to ;edge[num].dis = dis ; hea[from] = num ; } inline void add_edge(int u , int v , int w) {Insert_edge(u , v , w) ;Insert_edge(v , u , 0) ; } inline bool bfs() {queue < int > q ; q.push(S) ;memset(dep , 0 , sizeof(dep)) ; dep[S] = 1 ;while(!q.empty()) {int u = q.front() ; q.pop() ;for(int i = hea[u] ; i ; i = edge[i].nxt) {int v = edge[i].to ; if(!dep[v] && edge[i].dis > 0) {dep[v] = dep[u] + 1 ; q.push(v) ;}}}return dep[T] ; } int dfs(int u , int dis) {if(u == T || !dis) return dis ;int sum = 0 ;for(int i = hea[u] ; i ; i = edge[i].nxt) {int v = edge[i].to ; if(dep[v] == dep[u] + 1 && edge[i].dis > 0) {int diss = dfs(v , min(dis , edge[i].dis)) ;if(diss > 0) {edge[i].dis -= diss ; edge[i ^ 1].dis += diss ;sum += diss ; dis -= diss ; if(!dis) break ;}}}if(!sum) dep[u] = -1 ; return sum ; } inline int dinic() {int ans = 0 ;while(bfs())ans += dfs(S , INF) ;return ans ; } int main() {n = read() ; m = read() ; h = read() ; d = read() ;S = 0 ; T = n * m * h + 1 ;for(int k = 1 ; k <= h ; k ++)for(int i = 1 ; i <= n ; i ++)for(int j = 1 ; j <= m ; j ++) {id[i][j][k] = ++ cnt ;val[i][j][k] = read() ;}for(int i = 1 ; i <= n ; i ++)for(int j = 1 ; j <= m ; j ++) {for(int k = 1 ; k <= h ; k ++)add_edge(id[i][j][k - 1] , id[i][j][k] , val[i][j][k]) ;add_edge(id[i][j][h] , T , INF) ;}for(int i = 1 ; i <= n ; i ++)for(int j = 1 ; j <= m ; j ++)for(int k = d + 1 ; k <= h ; k ++)for(int t = 0 , x , y ; t < 4 ; t ++) {x = i + dx[t] , y = j + dy[t] ;if(x < 1 || y < 1 || x > n || y > m) continue ;add_edge(id[i][j][k] , id[x][y][k - d] , INF) ;}printf("%d\n",dinic()) ;return 0 ; }

轉(zhuǎn)載于:https://www.cnblogs.com/beretty/p/10726344.html

總結(jié)

以上是生活随笔為你收集整理的[HNOI2013]切糕的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。