並不對勁的 noi2006 網路收費

2022-05-08 20:36:12 字數 2632 閱讀 3579

題目略長,就從大視野上覆制了。

聽上去好像費用流,然而……

***************************表示略長的題目的分界線************************

網路已經成為當今世界不可或缺的一部分。每天都有數以億計的人使用網路進行學習、科研、娛樂等活動。然而,

不可忽視的一點就是網路本身有著龐大的執行費用。所以,向使用網路的人進行適當的收費是必須的,也是合理的

。my市ns中學就有著這樣乙個教育網路。網路中的使用者一共有2n個,編號依次為1, 2, 3, …, 2n。這些使用者之間

是用路由點和網線組成的。使用者、路由點與網線共同構成乙個滿二叉樹結構。樹中的每乙個葉子結點都是乙個使用者

,每乙個非葉子結點(灰色)都是乙個路由點,而每一條邊都是一條網線(見下圖,使用者結點中的數字為其編號)

my網路公司的網路收費方式比較奇特,稱為「配對收費」。即對於每兩個使用者i, j (1≤i < j ≤2n ) 進行收費。

由於使用者可以自行選擇兩種付費方式a、b中的一種,所以網路公司向學校收取的費用與每一位使用者的付費方式有關

。該費用等於每兩位不同使用者配對產生費用之和。 為了描述方便,首先定義這棵網路樹上的一些概念: 祖先:根

結點沒有祖先,非根結點的祖先包括它的父親以及它的父親的祖先; 管轄葉結點:葉結點本身不管轄任何葉結點

,非葉結點管轄它的左兒子所管轄的葉結點與它的右兒子所管轄的葉結點; 距離:在樹上連線兩個點之間的用邊

最少的路徑所含的邊數。 對於任兩個使用者i, j (1≤i)

由於最終所付費用與付費方式有關,所以ns中學的使用者希望能夠自行改變自己的付費方式以減少總付費。然而,由

於網路公司已經將每個使用者註冊時所選擇的付費方式記錄在案,所以對於使用者i,如果他/她想改變付費方式(由a

改為b或由b改為a),就必須支付ci元給網路公司以修改檔案(修改付費方式記錄)。 現在的問題是,給定每個用

戶註冊時所選擇的付費方式以及ci,試求這些使用者應該如何選擇自己的付費方式以使得ns中學支付給網路公司的總

費用最少(更改付費方式費用+配對收費的費用)。

輸入檔案中第一行有乙個正整數n。 第二行有2n個整數,依次表示1號,2號,…,2n號使用者註冊時的付費方式,每

乙個數字若為0,則表示對應使用者的初始付費方式為a,否則該數字為1,表示付費方式為b。 第三行有2n個整數,

表示每乙個使用者修改付費方式需要支付的費用,依次為c1, c2, …,cm 。( m=2n ) 以下2n-1行描述給定的兩兩用

戶之間的流量表f,總第(i + 3)行第j列的整數為fi, j+i 。(1≤i<2n,1≤j≤2n ? i) 所有變數的含義可以參

見題目描述。n≤10,0≤fi, j≤500,0≤ci≤500 000

你的程式只需要向輸出檔案輸出乙個整數,表示ns中學支付給網路公司的最小總費用。(單位:元)

21 0 1 0

2 2 10 9

10 1 2

2 13

8***************************表示略長的題目結束了的分界線************************

這麼長的題目告訴我們一定要學好政治。

收費方式看上去很複雜,實際上沒有想象中那麼複雜但是也很複雜,可以看成a少就收所有的a,b少就收所有的b。這樣用字首和就能解決收費的問題了。

根據n<10大概猜到應該是狀壓dp,進而猜出dp(x,y,z)表示到第x個點,有y個a(或y個b),且祖先的取捨方案為z的收費情況。

那麼問題就來了:用dp[x][y][z]表示的話,空間總共要佔(2^10)^3!這樣空間肯定會出問題。能不能將其中兩維合成一維呢?

經過一番不對勁的思考,發現每往下走一層,z就會增加一位,而y的最大值會減少一半。把這兩維放在同一維似乎不錯。

#include#include

#include

#include

#include

#include

#include

#define maxm 5050

#define maxk 2050

using

namespace

std;

intdp[maxk][maxm],n,m,c[maxk],f[maxk][maxk];

intli[maxk],ri[maxk], ab[maxk];

intread()

int solve(int x,int y,int z,int l,int r,int

lim)

if(x>=m)

dp[xi][xj]=sum;

return

sum;

}else

dp[xi][xj]=res;

return

res;

}}int

main()

memset(dp,-1,sizeof

(dp));

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

for(int j=1;j<=m;j++)

f[i][j]=f[i][j-1]+f[i][j];

int ans=0x7fffffff

;

for(int i=0;i<=m;i++)

cout

<

return0;

}

view code

並不對勁的splay

splay和不加任何旋轉一定會被卡的二叉搜尋樹的唯一區別就是每次操作把當前節點旋轉到根。旋轉有各種zig zag的組合方式,感覺很麻煩,並不對勁的人並不想講。其實可以找出一些共性將它們合併。設ls a 點a是其父親的左兒子 son a 0 a的左兒子,son a 1 a的右兒子,fa a a的父親。...

並不對勁的費用流

最小費用最大流肯定要保證最大流,所以它和最大流有一些類似的性質。如果把費用看成邊,就可以每次走最短路 保證費用最小 走到不能走為止 保證最大流 費用流版的ek就是這樣。需要注意的是,反向弧的邊權為它對應的正向弧的費用的相反數,所以最短路要用spfa來求。費用流版的dinic,又叫zkw費用流,還是多...

並不對勁的字尾陣列

字尾陣列sa x 表示排序後第x位在排序前的位置。這個東西的求法有兩種,一種是倍增,時間複雜度o n log n 或o n log2n 另一種是用不知道什麼方法做到的o n 至於第二種方法是什麼,並不對勁的人並不知道,所以只說倍增。考慮正常地比較兩個字串,都是從頭比較到尾 那麼,如果把兩個字串都斷成...