題目描述
«問題描述:
假設有n根柱子,現要按下述規則在這n根柱子中依次放入編號為1,2,3,…的球。
(1)每次只能在某根柱子的最上面放球。
(2)在同一根柱子中,任何2個相鄰球的編號之和為完全平方數。
試設計乙個演算法,計算出在n根柱子上最多能放多少個球。例如,在4 根柱子上最多可放11 個球。
«程式設計任務:
對於給定的n,計算在n根柱子上最多能放多少個球。
輸入輸出格式
輸入格式:
第1 行有1個正整數n,表示柱子數。
輸出格式:
程式執行結束時,將n 根柱子上最多能放的球數以及相應的放置方案輸出。檔案的第一行是球數。接下來的n行,每行是一根柱子上的球的編號。
輸入輸出樣例
輸入樣例#1: 複製
4 輸出樣例#1: 複製
11 1 8
2 7 9
3 6 10
4 5 11
【think】
剛開始的時候,我不知道該怎麼處理那個球數量不一定的情況。
後來發現可以每次都跑一遍dinic,假如有超過柱子數量的小球不能夠找到之前的點,就可以跳出了。
建圖:
之前選擇乙個較大的數,對於不超過55的柱子數量,小球個數的最大。。maxn
源點:s(0)
匯點:t(2*maxn+1)
將每乙個小球都要拆分成兩個,也就是拆點。
然後分別與源點和匯點,建立容量為1的邊。
每次增加完乙個小球之後,都要跑一遍dinic,判斷是否符合條件。
#include
#define max 600000
#define inf 0x3f3f3f3f
using
namespace
std;
int level[max];
int iter[max];
int maxn = 72312;
int t = maxn*2+1;
struct edge
;int next[max];
int vis[max];
vector
g[max];
void add_edge(int from, int to, int cap)
void bfs(int s)}}
}int dfs(int v, int t, int flow)}}
return0;}
int max_flow(int s, int t)
}}int main()
}add_edge(num+maxn, t, 1);
int f = max_flow(0, t);//每次都要跑dinic,找到邊的數量
ans -= f;
if(ans>n)//如果ans現在的個數大於柱子數量,說明會有小球沒有地方放。
break;
}printf("%d\n", num-1);
memset(next, 0, sizeof(next));
for(int i=maxn;ifor(int j=0;jif(e.cap>0)}}
memset(vis, 0, sizeof(vis));
for(int i=1;iif(vis[i]==0)
printf("\n");}}
return
0;}
洛谷P2765 魔術球問題
問題描述 假設有n根柱子,現要按下述規則在這n根柱子中依次放入編號為1,2,3,的球。1 每次只能在某根柱子的最上面放球。2 在同一根柱子中,任何2個相鄰球的編號之和為完全平方數。試設計乙個演算法,計算出在n根柱子上最多能放多少個球。例如,在4 根柱子上最多可放11 個球。程式設計任務 對於給定的n...
洛谷 P2765 魔術球問題
有n個柱子,編號為1,2 的小環,要將它們依次套在環上,要求直接接觸的兩小球的和為完全平方數,那麼最多可以套幾個小球。首先可以貪心,如果可以套在其他小球上,則套在其他小球上,反之,套在柱子上,直到沒有多餘柱子,可以證明這是對的,但我覺得還是網路流的做法比較重要。因為要依次取小球,那麼當答案為ans時...
洛谷 P2765 魔術球問題
問題描述 假設有n根柱子,現要按下述規則在這n根柱子中依次放入編號為1,2,3,的球。1 每次只能在某根柱子的最上面放球。2 在同一根柱子中,任何2個相鄰球的編號之和為完全平方數。試設計乙個演算法,計算出在n根柱子上最多能放多少個球。例如,在4 根柱子上最多可放11 個球。程式設計任務 對於給定的n...