線性規劃與網路流24題 4 魔術球

2021-07-23 05:36:05 字數 2286 閱讀 9679

【線性規劃與網路流24題 4】魔術球

description

假設有n根柱子,現要按下述規則在這n根柱子中依次放入編號為 1,2,3,...的球。

(1)每次只能在某根柱子的最上面放球。

(2)在同一根柱子中,任何2個相鄰球的編號之和為完全平方數。

試設計乙個演算法,計算出在n根柱子上最多能放多少個球。例如,在4 根柱子上最多可放11個球。

程式設計任務: 對於給定的n,計算在 n根柱子上最多能放多少個球。

input

第1 行有 1個正整數n,表示柱子數。(0

output

/*程式執行結束時,將 n 根柱子上最多能放的球數以及相應的放置方案輸出。

檔案的第一行是球數。接下來的n行,每行是一根柱子上的球的編號。

按字典序輸出方案

*/一行,包含乙個整數,表示最多能放的球數

sample input

4
sample output

11

/*1 8

2 7 9

3 6 10

4 5 11

*/

這個題難點在於:題目中建模的轉化:跟流量有什麼關係嗎?

其實是有的:要求最多能放的球數,因為柱子數是固定的,那麼:重疊的球數越多越好?!(不是廢話嗎)

當然不是:用流量的思路來說,就是要求最大流啊

所以主要思路是:列舉答案轉化為判定性問題,然後最小路徑覆蓋,可以轉化成二分圖最大匹配,從而用最大流解決

第一點:為什麼是列舉答案而不是二分?

在網路流中,建圖是乙個很大的板塊(花很多時間和空間)

如果是列舉答案,只需要在原來的圖上繼續尋找增廣路就可以了

如果是二分,那麼需要重新建圖,會很麻煩

第二點:如何拆點?

因為點數不定(是不斷增加的)

那麼,就不能採取i,i+n的這種平移形式的拆點

所以,用i<<1和i<<1|1是很好的方法

第三點:最小路徑覆蓋怎麼弄?

把每個球看作乙個頂點,就是編號較小的頂點向編號較大的頂點連線邊,條件是兩個球可以相鄰,即編號之和為完全平方數

每根柱子看做一條路徑,n根柱子要覆蓋掉所有點,乙個解就是乙個路徑覆蓋

列舉a的值,當最小路徑覆蓋數剛好大於n時終止,a-1就是最優解

第四點:如何找方案?

dfs找匹配的點

因為每條邊的容量都是1,如果這個點在方案中,那麼在陣列的flow中是有標記的

另外注意每個點連的,是另外乙個點拆點之後的點,需要分清楚是哪乙個,dfs一直走到頭即可

**如下:

#includeusing namespace std;

bool issqr(int x)

const int maxn=11000;

const int maxm=1200010;

const int inf=999999;

int n,m,k;

struct edgeedge[maxm];

int tol,head[maxn];

bool flag[maxn];

int path[maxn],num;

void init()

void addedge(int u,int v,int w,int rw=0)

int q[maxn],dep[maxn],cur[maxn],sta[maxn];

bool bfs(int s,int t,int n)

} }return false;

}int dinic(int s,int t,int n)

u=edge[sta[tail]^1].to;

}else if (cur[u]!=-1&&edge[cur[u]].cap>edge[cur[u]].flow&&dep[u]+1==dep[edge[cur[u]].to])

else

} }return maxflow;

}void getpath(int u)

}int main()

//printf("%d\n",--ans);

printf("%d\n",--ans);

/* memset(flag,false,sizeof(flag));

for(int i=1;i<=ans;i++)

if (!flag[i])

*/ return 0;

}

線性規劃與網路流24 魔術球問題

題目點這裡 最小路徑覆蓋問題 這道題,一開始我花了100多ms,看了下排行榜,發現個10多ms的。看了很久他的 才明白怎麼回事。同時更加加深了我對匈牙利演算法的理解。我從他的 中學到的是 1 若多加幾條邊,並不需要重新跑一邊匈牙利,只需要從沒匹配的點開始dfs就可以了,2 若因為多加了乙個點,從而多...

線性規劃與網路流24題 04魔術球問題

1739 魔術球問題 time limit 1000ms memory limit 65536k total submit 39accepted 20 page view 230 special judged submit status discuss font size aa aa aa 假設有n...

網路流 24 題 4 魔術球

題意 有n根柱子可以放球,球上的權值從1向後標。要求這n根柱子滿足 任意一根柱子上相鄰兩個球的和是乙個完全平方數 小的球在下面,大的球在上面 輸出最多放多少個球,和其中的一種方案。分析 第一想法是打表,是不是沒救了 然後首先就是考慮到了二分.然而範圍十分神奇.可以說是猜出來的。然後就是考慮把一些球連...