方格取數加強版

2021-08-11 11:34:09 字數 1229 閱讀 7821

給出乙個n*n的矩陣,每一格有乙個非負整數aij,(aij <= 1000)現在從(1,1)出發,可以往右或者往下走,最後到達(n,n),每達到一格,把該格仔的數取出來,該格仔的數就變成0,這樣一共走k次,現在要求k次所達到的方格的數的和最大

輸入格式:

第一行兩個數n,k(1<=n<=50, 0<=k<=10)

接下來n行,每行n個數,分別表示矩陣的每個格仔的數

輸出格式:

乙個數,為最大和

二取方格數是乙個經典的dp題,然而這題的資料範圍變成了n<=50,十取方格數。顯然不能用dp。。

昨天的數字梯形同樣是取數,我們這道題也可以費用流。取數=費用。

我們要限制每個點只能取一次怎麼辦呢?拆點建一條邊,費用=取數大小,只能走一次所以容量是1.

乙個點是可以重複走的,所以還需要再加一條邊,容量=inf。

s連11入點 t連nn出點,跑一遍最大費用最大流就好了。

#include

using

namespace

std;

const

int maxn=3e5+5;

const

int base=1e5;

const

int inf=1e9;

struct edgee[maxn<<1];

int head[maxn],cnt=1,pre[maxn],dis[maxn];

inline

void add(int u,int v,int w,int cost),head[u]=cnt;}

int n,m,s,t;

bool vis[maxn];

queue

q;bool spfa(int x)}}

}}

if(dis[t]==-inf)return

0; return1;}

int mf()

for(int i=pre[t];i;i=pre[e[i].u])

}return cost;

}int main()//i入,i+base出

add(s,1,m,0),add(1,s,0,0);

add(n*n+base,t,m,0),add(t,n*n+base,0,0);

for(int i=1;i<=n*n;i++)

printf("%d\n",mf());

return

0;}

方格取數加強版 題解

因為乙個點的貢獻只能算一次,把點拆成2個點即可,連一條流量為 1 費用為這個點的值,然後再連一條流量為 infty 費用為 0 的邊,接下來對於每個點向它下方和它右方的點連一條流量為 infty 費用為 0 的邊即可。算最大費用,邊權取反。include int n,k,s,t,mincost in...

luogu P2045 方格取數加強版

題目傳送門 題意 有乙個n n的矩陣,每乙個點都有對應的權值,現在你可以走k次,求你能獲得的最大價值。注意 每個點選完之後權值變為0。思路 最大費用最大流啊。1.因為只能選k次,所以開乙個超級源點和超級匯點,分別連向 1,1 和 n,n 流量為k。2.因為每個點的權值只能選一次,所以拆點。1 每乙個...

P2045 方格取數加強版

給出乙個n n的矩陣,每一格有乙個非負整數aij,aij 1000 現在從 1,1 出發,可以往右或者往下走,最後到達 n,n 每達到一格,把該格仔的數取出來,該格仔的數就變成0,這樣一共走k次,現在要求k次所達到的方格的數的和最大 輸入格式 第一行兩個數n,k 1 n 50,0 k 10 接下來n...