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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

[Vijos 1143]三取方格数

發布時間:2023/12/13 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Vijos 1143]三取方格数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Description

設有N*N的方格圖,我們將其中的某些方格填入正整數,
而其他的方格中放入0。

某人從圖得左上角出發,可以向下走,也可以向右走,直到到達右下角。

在走過的路上,他取走了方格中的數。(取走后方格中數字變為0)
此人從左上角到右下角共走3次,試找出3條路徑,使得取得的數總和最大。

Input

第一行:N (4<=N<=20)
接下來一個N*N的矩陣,矩陣中每個元素不超過80,不小于0

Output

一行,表示最大的總和。

Sample Input

4 1 2 3 4 2 1 3 4 1 2 3 4 1 3 2 4

Sample Output

39

題解(轉載)

->原文地址<-

$DP$好題。

這里給出費用流的做法:

拆點建圖,每一個點都拆成兩個點,在這里就稱為出點和入點。

出點和入點建兩條邊,一條費用為$s[i][j]$,流量為$1$;一條費用為$0$,流量為$inf$。(分別表示選擇這個點和從這個點上經過)

將$(i,j)$的出點分別和$(i+1,j)$$(i,j+1)$的入點建邊,流量為$inf$,費用為$0$。(表示行進)

跑一邊最大費用最大流就可以了。

1 #include <set> 2 #include <map> 3 #include <ctime> 4 #include <cmath> 5 #include <queue> 6 #include <stack> 7 #include <vector> 8 #include <cstdio> 9 #include <string> 10 #include <cstring> 11 #include <cstdlib> 12 #include <iostream> 13 #include <algorithm> 14 #define LL long long 15 #define Max(a, b) ((a) > (b) ? (a) : (b)) 16 #define Min(a, b) ((a) < (b) ? (a) : (b)) 17 using namespace std; 18 const int INF = ~0u>>1; 19 20 int n; 21 int a[25][25]; 22 struct tt{ 23 int to, cost, next, cap; 24 }edge[5005]; 25 int path[1005], top = -1; 26 void Add(int u, int v, int cost, int cap); 27 int sta = 999, fin = 1000; 28 int min_cost_flow(); 29 int SPFA(); 30 31 int main(){ 32 memset(path, -1, sizeof(path)); 33 scanf("%d", &n); 34 for (int i = 0; i < n; i++) 35 for (int j = 0; j < n; j++) 36 scanf("%d", &a[i][j]); 37 for (int i = 0; i < n; i++) 38 for (int j = 0; j < n; j++){ 39 Add(i*n+j, (i+n)*n+j, a[i][j], 1); 40 Add(i*n+j, (i+n)*n+j, 0, INF); 41 if (i != n-1) Add((i+n)*n+j, (i+1)*n+j, 0, INF); 42 if (j != n-1) Add((i+n)*n+j, i*n+j+1, 0, INF); 43 } 44 Add(sta, 0, 0, 3); 45 Add((2*n-1)*n+n-1, fin, 0 ,3); 46 printf("%d\n", min_cost_flow()); 47 return 0; 48 } 49 50 void Add(int u, int v, int cost, int cap){ 51 edge[++top].to = v; 52 edge[top].cost = cost; 53 edge[top].cap = cap; 54 edge[top].next = path[u]; 55 path[u] = top; 56 edge[++top].to = u; 57 edge[top].cost = -cost; 58 edge[top].cap = 0; 59 edge[top].next = path[v]; 60 path[v] = top; 61 } 62 int min_cost_flow(){ 63 int tolcost = 0; 64 int tmp; 65 while (tmp = SPFA()) tolcost += tmp; 66 return tolcost; 67 } 68 int SPFA(){ 69 int dist[1005]; 70 memset(dist, 128, sizeof(dist)); dist[sta] = 0; dist[fin] = -INF; 71 bool vis[1005] = {0}; vis[sta] = 1; 72 queue<int>Q; 73 while (!Q.empty()) Q.pop(); 74 Q.push(sta); 75 int pre[1005] = {0}; 76 while (!Q.empty()){ 77    int u = Q.front(); Q.pop(); vis[u]=0; 78    for (int i = path[u]; i != -1; i = edge[i].next){ 79    int v = edge[i].to; 80    if (dist[v] < dist[u]+edge[i].cost && edge[i].cap > 0){ 81      dist[v] = dist[u]+edge[i].cost; 82      pre[v] = i; 83      if (!vis[v]){ 84      vis[v] = 1; 85      Q.push(v); 86      } 87    } 88    } 89 } 90 if (dist[fin] == -INF) return 0; 91 int minflow = INF; 92 for (int i = fin; i != sta; i = edge[pre[i]^1].to) 93    minflow = Min(minflow, edge[pre[i]].cap); 94 for (int i = fin; i != sta; i = edge[pre[i]^1].to) 95    edge[pre[i]].cap -= minflow, 96    edge[pre[i]^1].cap += minflow; 97 return dist[fin]; 98 }

?

轉載于:https://www.cnblogs.com/NaVi-Awson/p/7460488.html

總結

以上是生活随笔為你收集整理的[Vijos 1143]三取方格数的全部內容,希望文章能夠幫你解決所遇到的問題。

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