【線性規劃與網路流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
4sample 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根柱子滿足 任意一根柱子上相鄰兩個球的和是乙個完全平方數 小的球在下面,大的球在上面 輸出最多放多少個球,和其中的一種方案。分析 第一想法是打表,是不是沒救了 然後首先就是考慮到了二分.然而範圍十分神奇.可以說是猜出來的。然後就是考慮把一些球連...